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

    题意:给定n<=105的数组h,有m<=105的询问,每个询问为l,r,w求[l,r]区间内连续w个的最小高度最大是多少..

    思路:首先把h数组从大到小排序,然后用建立一个可持久化的下标线段树,线段树维护区间最长的连续长度为多少。

            那么对于每个询问直接二分高度,然后查询这个高度之前的线段树[l,r]区间是否存在至少w个连续的。。

            以前总是套主席树模板,这次自己写感觉也还是蛮好写的。。

           据说cdq分治也可搞。。应该是整体二分吧。。明天再想想

    code:

      1 /*
      2  * Author:  Yzcstc
      3  * Created Time:  2014/11/10 22:17:29
      4  * File Name: cf276E.cpp
      5  */
      6 #include<cstdio>
      7 #include<iostream>
      8 #include<cstring>
      9 #include<cstdlib>
     10 #include<cmath>
     11 #include<algorithm>
     12 #include<string>
     13 #include<map>
     14 #include<set>
     15 #include<vector>
     16 #include<queue>
     17 #include<stack>
     18 #include<ctime>
     19 #define M0(a) memset(a, 0, sizeof(a))
     20 #define N 101010
     21 #define M 3100000
     22 #define x first
     23 #define y second
     24 #define ls lson[rt]
     25 #define rs rson[rt]
     26 using namespace std;
     27 typedef pair<int, int> pii;
     28 struct node{
     29      int c, lc, rc;
     30      node(int _c = 0, int _lc = 0, int _rc = 0):c(_c), lc(_lc), rc(_rc){}
     31 };
     32 pair<int, int> p[N];
     33 int T[N], lc[M], rc[M], c[M], lson[M], rson[M], tot;
     34 int n, m;
     35 
     36 int build(const int l, const int r){
     37     int root = tot++;
     38     c[root] = lc[root] = rc[root] = 0;
     39     if (l < r){
     40          int mid = (l + r) >> 1;
     41          lson[root] = build(l, mid);
     42          rson[root] = build(mid+1, r);
     43     }
     44     return root;
     45 }
     46 
     47 void push_up(const int& rt, const int& llen, const int &rlen){
     48      lc[rt] = (c[ls] >= llen) ? llen + lc[rs] : lc[ls];
     49      rc[rt] = (c[rs] >= rlen) ? rlen + rc[ls] : rc[rs];
     50      c[rt] = max(c[ls], c[rs]), c[rt] = max(lc[rs] + rc[ls], c[rt]);
     51 }
     52 
     53 int update(const int rt, const int l, const int r, const int& p){
     54     int root = tot++;
     55     if (p <= l && r <= p){
     56           c[root] = rc[root] = lc[root] = 1;
     57           return root;
     58     }
     59     int mid = (l + r) >> 1;
     60     lson[root] = ls, rson[root] = rs;
     61     if (p <= mid)
     62           lson[root] = update(ls, l, mid, p);
     63     else 
     64           rson[root] = update(rs, mid+1, r, p);
     65     push_up(root, mid-l+1, r-mid);
     66     return root;
     67 }
     68 
     69 node tmp, t;
     70 void merge(node &a, const node& b,const int& llen,const int& rlen){
     71      t.c = max(a.c, b.c), t.c = max(t.c, a.rc + b.lc);
     72      t.lc = (a.lc >= llen) ? a.lc + b.lc : a.lc;
     73      t.rc = (b.rc >= rlen) ? b.rc + a.rc : b.rc;
     74      a = t;
     75 }
     76 
     77 node query(const int& rt,const int& l,const int& r,const int& L,const int& R){
     78     if (L <= l && r <= R) return node(c[rt], lc[rt], rc[rt]);
     79     int mid = (l + r) >> 1;
     80     if (R <= mid) return query(ls, l, mid, L, R);
     81     else if (L > mid) return query(rs, mid + 1, r, L, R);
     82     else{
     83          node res = query(ls, l, mid, L, R);
     84          tmp = query(rs, mid+1, r, L, R);
     85          merge(res, tmp, mid - max(L, l) + 1, min(R,r) - mid);
     86          return res;
     87     }
     88 }
     89 
     90 void init(){
     91      scanf("%d", &n);
     92      tot = 0;
     93      for (int i = 1; i <= n; ++i)
     94          scanf("%d", &p[i].x), p[i].y = i;
     95      sort(p + 1, p + 1 + n, greater<pii>() );
     96 }
     97 
     98 void solve(){
     99      T[0] = build(1, n);
    100      for (int i = 1; i <= n; ++i)
    101            T[i] = update(T[i-1], 1, n, p[i].y);
    102      int q, ll, rr, w, l, r, mid, ans;
    103      scanf("%d", &q);
    104      while (q--){
    105          scanf("%d%d%d", &ll, &rr, &w);
    106          l = 1, r = n, ans = 0;
    107          while (l <= r){
    108                mid = (l + r) >> 1;
    109                if (query(T[mid], 1, n, ll, rr).c >= w){
    110                        ans = max(ans, p[mid].x);
    111                        r = mid - 1;
    112                } else l = mid + 1;
    113          }
    114          printf("%d
    ", ans);
    115      }
    116            
    117 }
    118 
    119 
    120 int main(){
    121     init();
    122     solve();
    123     return 0;
    124 }
    View Code
  • 相关阅读:
    暑假第二周总结
    7.18-7.24 第一周周报
    poj 3295 Tautology
    2016多校 #2 1006 Fantasia
    codeforces 698B Fix a Tree
    codeforces 699B Bomb
    HDU 4578(线段树
    CF 600F( 二分图
    hdu 5517 Triple(二维树状数组)
    HDU HDOJ5412(树套树or整体二分
  • 原文地址:https://www.cnblogs.com/yzcstc/p/4088566.html
Copyright © 2011-2022 走看看