zoukankan      html  css  js  c++  java
  • CF 484E

    E. Sign on Fence
    time limit per test
    4 seconds
    memory limit per test
    256 megabytes
    input
    standard input
    output
    standard output

    Bizon the Champion has recently finished painting his wood fence. The fence consists of a sequence of n panels of 1 meter width and of arbitrary height. The i-th panel's height is hi meters. The adjacent planks follow without a gap between them.

    After Bizon painted the fence he decided to put a "for sale" sign on it. The sign will be drawn on a rectangular piece of paper and placed on the fence so that the sides of the sign are parallel to the fence panels and are also aligned with the edges of some panels. Bizon the Champion introduced the following constraints for the sign position:

    1. The width of the sign should be exactly w meters.
    2. The sign must fit into the segment of the fence from the l-th to the r-th panels, inclusive (also, it can't exceed the fence's bound in vertical direction).

    The sign will be really pretty, So Bizon the Champion wants the sign's height to be as large as possible.

    You are given the description of the fence and several queries for placing sign. For each query print the maximum possible height of the sign that can be placed on the corresponding segment of the fence with the given fixed width of the sign.

    Input

    The first line of the input contains integer n — the number of panels in the fence (1 ≤ n ≤ 105).

    The second line contains n space-separated integers hi, — the heights of the panels (1 ≤ hi ≤ 109).

    The third line contains an integer m — the number of the queries (1 ≤ m ≤ 105).

    The next m lines contain the descriptions of the queries, each query is represented by three integers lr and w (1 ≤ l ≤ r ≤ n,1 ≤ w ≤ r - l + 1) — the segment of the fence and the width of the sign respectively.

    Output

    For each query print the answer on a separate line — the maximum height of the sign that can be put in the corresponding segment of the fence with all the conditions being satisfied.

    Sample test(s)
    input
    5
    1 2 2 3 3
    3
    2 5 3
    2 5 2
    1 5 5
    output
    2
    3
    1
    Note

    The fence described in the sample looks as follows:

    The possible positions for the signs for all queries are given below.

    The optimal position of the sign for the first query.
    The optimal position of the sign for the second query.

     CF上的一道题,给你若干个高度不一的木板,高度为h1...hn,回答m次询问,每次询问(l,r,w)表示l...r区间内,用宽度不小于w的长条覆盖木板,长条的最大高度是多少。

    CF给的题解是用函数式线段树,维护各个区间内木板高度的线段树,二分答案然后查询函数式线段树中最大的连续“1”的长度,进行比较。

    可以用函数式线段树做的题,一般也可以用整体二分做。相当于一个是在线二分,一个是离线二分。

    整体二分的思路是:

    二分答案,把高度>mid的木板插入到线段树中,某位置有木板为1,没有为0。

    对于询问,统计最大的连续“1”的长度,然后和w比较,长度>=w就往[mid+1,r]区间划分,<w就往[l,mid]区间划分。

    这样二分到底层,所有询问的答案也就确定了。

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <algorithm>
      4 #include <cstring>
      5 #include <cmath>
      6 #include <vector>
      7 #define inf 1000000007
      8 #define maxn 420000
      9 #define maxm 420000
     10 
     11 using namespace std;
     12 
     13 int n,m,tot,cnt;
     14 int a[maxn], ans[maxm];
     15 
     16 struct query
     17 {
     18     int id,x,y,z,cur;
     19     query(){}
     20     query(int id,int x,int y,int z,int cur):
     21         id(id),x(x),y(y),z(z),cur(cur){}
     22 }q[maxm],q1[maxm],q2[maxm];
     23 
     24 struct segtree
     25 {
     26     int mx[maxn*8], lmx[maxn*8], rmx[maxn*8], size[maxn*8];
     27     void update(int x)
     28     {
     29         mx[x]=max(max(mx[x*2],mx[x*2+1]),rmx[x*2]+lmx[x*2+1]);
     30         if (lmx[x*2]==size[x*2]) lmx[x]=size[x*2]+lmx[x*2+1];
     31         else lmx[x]=lmx[x*2];
     32         if (rmx[x*2+1]==size[x*2+1]) rmx[x]=size[x*2+1]+rmx[x*2];
     33         else rmx[x]=rmx[x*2+1];
     34     }
     35     void build(int x,int l,int r)
     36     {
     37         if (l==r)
     38         {
     39             size[x]=1;
     40             return ;
     41         }
     42         int mid=(l+r)>>1;
     43         build(x*2,l,mid);
     44         build(x*2+1,mid+1,r);
     45         size[x]=size[x*2]+size[x*2+1];
     46     }
     47     void add(int x, int l, int r, int pos, int z)
     48     {
     49         if (l==r)
     50         {
     51             mx[x]=lmx[x]=rmx[x]=z;
     52             return ;
     53         }
     54         int mid=(l+r)>>1;
     55         if (pos<=mid) add(x*2, l, mid, pos, z);
     56         else add(x*2+1, mid+1, r, pos, z);
     57         update(x);
     58     }
     59     int ask(int x, int l, int r, int ll, int rr, int &res)
     60     {
     61         if (ll<=l && r<=rr)
     62         {
     63             int tmp=max(res+lmx[x], mx[x]);
     64             if (rmx[x]==size[x]) res+=size[x];
     65             else res=rmx[x];
     66             return tmp;
     67         }
     68         int mid=(l+r)>>1, tmp=0;
     69         if (ll<=mid) tmp=max(tmp,ask(x*2, l, mid, ll, rr, res));
     70         if (rr>mid) tmp=max(tmp,ask(x*2+1, mid+1, r, ll, rr, res));
     71         return tmp;
     72     }
     73     void init()
     74     {
     75         memset(mx,0,sizeof(mx));
     76         memset(lmx,0,sizeof(lmx));
     77         memset(rmx,0,sizeof(rmx));
     78     }
     79 }tree;
     80 
     81 void solve(int st,int ed,int l,int r)
     82 {
     83     if (st>ed) return ;
     84     if (l>=r)
     85     {
     86         for (int i=st;i<=ed;i++) ans[q[i].id]=l;
     87         return ;
     88     }
     89     int mid=(l+r)>>1, n1=0, n2=0;
     90     for (int i=st;i<=ed;i++)
     91     {
     92         if (q[i].id==0)
     93         {
     94             if (q[i].y>mid)
     95             {
     96                 tree.add(1, 1, n, q[i].x, 1);
     97                 q2[n2++]=q[i];
     98             }
     99             else
    100                 q1[n1++]=q[i];
    101         }
    102         else
    103         {
    104             int res=0;
    105             int tmp=tree.ask(1, 1, n, q[i].x, q[i].y, res);
    106             if (tmp>=q[i].z) 
    107                 q2[n2++]=q[i];
    108             else 
    109                 q1[n1++]=q[i];
    110         }
    111     }
    112     for (int i=0;i<n1;i++) q[st+i]=q1[i];
    113     for (int i=0;i<n2;i++) q[st+n1+i]=q2[i];
    114     solve(st,st+n1-1,l,mid);
    115     for (int i=st;i<=ed;i++)
    116         if (q[i].id==0 && q[i].y>mid) tree.add(1, 1, n, q[i].x, 0);
    117     solve(st+n1,ed,mid+1,r);
    118 }
    119 
    120 int main()
    121 {
    122     scanf("%d",&n);
    123     tot=0;
    124     for (int i=1;i<=n;i++)
    125     {
    126         scanf("%d",&a[i]);
    127         q[tot++]=query(0,i,a[i],0,0);
    128     }
    129     scanf("%d",&m);
    130     int x,y,z;
    131     for (int i=1;i<=m;i++)
    132     {
    133         scanf("%d%d%d",&x,&y,&z);
    134         q[tot++]=query(i,x,y,z,0);
    135     }
    136     tree.init();
    137     tree.build(1,1,n);
    138     solve(0,tot-1,0,inf);
    139     for (int i=1;i<=m;i++) printf("%d
    ",ans[i]);
    140     return 0;
    141 }
    Sign on Fence
  • 相关阅读:
    信息学奥赛一本通(C++)在线评测系统——基础(一)C++语言——1092:求出e的值
    信息学奥赛一本通(C++)在线评测系统——基础(一)C++语言——1092:求出e的值
    信息学奥赛一本通(C++)在线评测系统——基础(一)C++语言——1091:求阶乘的和
    信息学奥赛一本通(C++)在线评测系统——基础(一)C++语言——1091:求阶乘的和
    信息学奥赛一本通(C++)在线评测系统——基础(一)C++语言——1090:含k个3的数
    信息学奥赛一本通(C++)在线评测系统——基础(一)C++语言——1090:含k个3的数
    CodeForces 679B(Bear and Tower of Cubes)
    uva247 Calling Circles(传递闭包+DFS)
    uva673 Parentheses Balance(栈)
    uva439 Knight Moves(BFS求最短路)
  • 原文地址:https://www.cnblogs.com/zig-zag/p/4790905.html
Copyright © 2011-2022 走看看