zoukankan      html  css  js  c++  java
  • 线段树(3)

    hdu 4614  Vases and Flowers

    0~n-1的区间,初始值为0,m个操作。
    两种操作:
    1 X Y 从位置X开始寻找Y个0,如果不足Y个,则寻找尽量多的0,并将他们的值全部修改为1,输出第一个和最后一个修改的1的位置。
    2 X Y 输出区间[ X , Y ]内1的个数,并将区间内的1修改为0。

    做法:记录区间内1的个数。。关键是第一种操作,ret表示区间[x,n]内0的个数,tmp表示[1,x-1]内0的个数。查询的时候看ls内0的个数是不是大于等于c。

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cmath>
      4 #include<string>
      5 #include<cstring>
      6 #include<algorithm>
      7 #include<set>
      8 using namespace std;
      9 
     10 #define ULL unsigned long long
     11 #define eps 1e-9
     12 #define inf 0x3f3f3f3f
     13 #define ls i << 1
     14 #define rs ls | 1
     15 #define md ((ll + rr) >> 1)
     16 #define lson ll, md, ls
     17 #define rson md + 1, rr, rs
     18 #define LL long long
     19 #define N 50010
     20 #define M 200020
     21 #define mod 1000000007
     22 
     23 int sum[N<<2], down[N<<2];
     24 void build(int ll, int rr, int i){
     25     sum[i] = 0, down[i] = -1;
     26     if(ll == rr) return ;
     27     build(lson), build(rson);
     28 }
     29 void push_down(int i, int ll, int rr){
     30     if(down[i] != -1){
     31         down[ls] = down[rs] = down[i];
     32         sum[ls] = down[i] ? md - ll + 1 : 0;
     33         sum[rs] = down[i] ? rr - md : 0;
     34         down[i] = -1;
     35     }
     36 }
     37 void push_up(int i){
     38     sum[i] = sum[ls] + sum[rs];
     39 }
     40 void update(int l, int r, int v, int ll, int rr, int i){
     41     if(l == ll && r == rr){
     42         down[i] = v;
     43         sum[i] = v ? rr - ll + 1 : 0;
     44         return ;
     45     }
     46     push_down(i, ll, rr);
     47     if(r <= md) update(l, r, v, lson);
     48     else if(l > md) update(l, r, v, rson);
     49     else update(l, md, v, lson), update(md+1, r, v, rson);
     50     push_up(i);
     51 }
     52 int query(int l, int r, int ll, int rr, int i){
     53     if(l == ll && r == rr)
     54         return sum[i];
     55     push_down(i, ll, rr);
     56     int ret;
     57     if(r <= md) ret = query(l, r, lson);
     58     else if(l > md) ret = query(l, r, rson);
     59     else ret = query(l, md, lson) + query(md + 1, r, rson);
     60     push_up(i);
     61     return ret;
     62 }
     63 
     64 int qR(int c, int ll, int rr, int i){
     65     if(ll == rr)
     66         return ll;
     67     push_down(i, ll, rr);
     68     int ret;
     69     int tmp = md - ll + 1 - sum[ls];
     70     if(tmp >= c)
     71         ret = qR(c, lson);
     72     else ret = qR(c - tmp, rson);
     73     push_up(i);
     74     return ret;
     75 }
     76 int main(){
     77     int cas;
     78     //freopen("tt.txt", "r", stdin);
     79     scanf("%d", &cas);
     80     while(cas--){
     81         int n, m;
     82         scanf("%d%d", &n, &m);
     83         build(1, n, 1);
     84         while(m--){
     85             int op, x, y;
     86             scanf("%d%d%d", &op, &x, &y);
     87             if(op == 1){
     88                 x++;
     89                 int ret = n - x + 1 - query(x, n, 1, n, 1);
     90                 int tmp = n - sum[1] - ret;
     91                 if(ret == 0){
     92                     puts("Can not put any one."); continue;
     93                 }
     94                 y = min(y, ret);
     95                 int l = qR(1 + tmp, 1, n, 1);
     96                 int r = qR(y + tmp, 1, n, 1);
     97                 update(l, r, 1, 1, n, 1);
     98                 l--, r--;
     99                 printf("%d %d
    ", l, r);
    100             }
    101             else{
    102                 x++, y++;
    103                 printf("%d
    ", query(x, y, 1, n, 1));
    104                 update(x, y, 0, 1, n, 1);
    105             }
    106         }
    107         puts("");
    108     }
    109     return 0;
    110 }
    View Code

     zoj 3299 Fall the Brick

    有n个木块,m个板。木块从上往下掉,覆盖的范围是[l, r],板的高度h不一样,能够接到木块的范围是[L, R],问每块板上能接多少木块。

    做法:离散化,先确定每个区间的id,然后线段树区间更新。最后再做一次query。

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cmath>
      4 #include<string>
      5 #include<cstring>
      6 #include<algorithm>
      7 #include<ctime>
      8 #include<cstdlib>
      9 #include<queue>
     10 using namespace std;
     11 
     12 #define ULL unsigned long long
     13 #define eps 1e-9
     14 #define inf 0x3f3f3f3f
     15 #define ls i << 1
     16 #define rs ls | 1
     17 #define md ((ll + rr) >> 1)
     18 #define lson ll, md, ls
     19 #define rson md + 1, rr, rs
     20 #define LL long long
     21 #define mod 1000000007
     22 #define N 100020
     23 #define M 800020
     24 
     25 LL ans[N], a[N<<2];
     26 int add[N<<4], id[N<<4];
     27 void push_down(int i){
     28     if(id[i]){
     29         id[ls] = id[rs] = id[i];
     30         id[i] = 0;
     31     }
     32     if(add[i]){
     33         add[ls] += add[i], add[rs] += add[i];
     34         add[i] = 0;
     35     }
     36 }
     37 void update(int l, int r, int u, int ll, int rr, int i){
     38     if(l == ll && r == rr){
     39         if(u) id[i] = u;
     40         else add[i]++;
     41         return ;
     42     }
     43     push_down(i);
     44     if(r <= md) update(l, r, u, lson);
     45     else if(l > md) update(l, r, u, rson);
     46     else update(l, md, u, lson), update(md + 1, r, u, rson);
     47 }
     48 
     49 void query(int ll, int rr, int i){
     50     if(ll == rr){
     51         ans[id[i]] += (LL)(a[rr+1] - a[rr]) * add[i];
     52         return;
     53     }
     54     push_down(i);
     55     query(lson), query(rson);
     56 }
     57 struct query{
     58     int L, R, H, id;
     59     void input(int i){
     60         scanf("%d%d%d", &L, &R, &H);
     61         id = i;
     62     }
     63     bool operator < (const query &b) const {
     64         return H < b.H;
     65     }
     66 }q[N];
     67 int L[N], R[N];
     68 int main(){
     69     int n, m;
     70     while(scanf("%d%d", &n, &m) != EOF){
     71         memset(ans, 0, sizeof ans);
     72         memset(id, 0, sizeof id);
     73         memset(add, 0, sizeof add);
     74         int cnt = 0;
     75         for(int i = 1; i <= n; ++i){
     76             scanf("%d%d", &L[i], &R[i]);
     77             a[++cnt] = L[i], a[++cnt] = R[i];
     78         }
     79         for(int i = 1; i <= m; ++i){
     80             q[i].input(i);
     81             a[++cnt] = q[i].L, a[++cnt] = q[i].R;
     82         }
     83         sort(a + 1, a + 1 + cnt);
     84         cnt = unique(a + 1, a + 1 + cnt) - a - 1;
     85         sort(q + 1, q + 1 + m);
     86         for(int i = 1; i <= m; ++i){
     87             int l = lower_bound(a + 1, a + 1 + cnt, q[i].L) - a;
     88             int r = lower_bound(a + 1, a + 1 + cnt, q[i].R) - a;
     89             update(l, r - 1, q[i].id, 1, cnt, 1);
     90         }
     91         for(int i = 1; i <= n; ++i){
     92             int l = lower_bound(a + 1, a + 1 + cnt, L[i]) - a;
     93             int r = lower_bound(a + 1, a + 1 + cnt, R[i]) - a;
     94             update(l, r - 1, 0, 1, cnt, 1);
     95         }
     96         query(1, cnt, 1);
     97         for(int i = 1; i <= m; ++i){
     98             printf("%lld
    ", ans[i]);
     99         }
    100         puts("");
    101     }
    102     return 0;
    103 }
    View Code

    CF 266E More Queries to Array...

    给你一串数,编号从1~n,进行m次操作。(1 <= n , m <= 10 ^ 5 )

    = L R X 区间【L,R】上的数设为X

    ?L R K 输出  。

    做法:对询问进行二项式展开,得到 segma(j = 0, k)[C(k, j) * (1 - l)^(k - j)] * segma(i = l, r)[ai * i^j]。。由于0 <= k <= 5,对于后面部分可以直接开6棵线段树保存。然后前面部分预处理出组合数,询问的时候乘上就好了。

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <algorithm>
      5 #include <cmath>
      6 #include <queue>
      7 #include <stack>
      8 using namespace std;
      9 
     10 #define LL long long
     11 #define eps 1e-8
     12 #define inf 0x3f3f3f3f
     13 #define MP make_pair
     14 #define N 100020
     15 #define M 400020
     16 #pragma comment(linker, "/STACK:1024000000,1024000000")
     17 #define Pi acos(-1.0)
     18 #define mod 1000000007
     19 #define ls (i << 1)
     20 #define rs (ls | 1)
     21 #define md ((ll + rr) >> 1)
     22 #define lson ll, md, ls
     23 #define rson md + 1, rr, rs
     24 
     25 LL c[10][10], s[N][6];
     26 void init(){
     27     c[0][0] = 1;
     28     for(int i = 1; i <= 6; ++i){
     29         c[i][0] = 1;
     30         for(int j = 1; j <= i; ++j)
     31             c[i][j] = c[i-1][j] + c[i-1][j-1];
     32     }
     33     for(int i = 0; i < N; ++i){
     34         for(int j = 0; j < 6; ++j){
     35             s[i][j] = 1;
     36             for(int k = 0; k < j; ++k)
     37                 s[i][j] = s[i][j] * i % mod;
     38         }
     39     }
     40     for(int i = 1; i < N; ++i)
     41         for(int j = 0; j < 6; ++j)
     42             s[i][j] = (s[i][j] + s[i-1][j]) % mod;
     43 }
     44 LL sum[N<<2][6];
     45 int down[N<<2];
     46 void f(int v, int ll, int rr, int i){
     47     down[i] = v;
     48     for(int j = 0; j < 6; ++j)
     49         sum[i][j] = (s[rr][j] - s[ll-1][j] + mod) % mod * v % mod;
     50 }
     51 void push_down(int i, int ll, int rr){
     52     if(~down[i]){
     53         f(down[i], lson);
     54         f(down[i], rson);
     55         down[i] = -1;
     56     }
     57 }
     58 void push_up(int i){
     59     for(int j = 0; j < 6; ++j)
     60         sum[i][j] = (sum[ls][j] + sum[rs][j]) % mod;
     61 }
     62 void build(int ll, int rr, int i){
     63     down[i] = -1;
     64     if(ll == rr){
     65         int v;
     66         scanf("%d", &v);
     67         for(int j = 0; j < 6; ++j)
     68             sum[i][j] = (s[rr][j] - s[rr-1][j] + mod) % mod * v % mod;
     69         return ;
     70     }
     71     build(lson), build(rson);
     72     push_up(i);
     73 }
     74 
     75 void update(int l, int r, int v, int ll, int rr, int i){
     76     if(l == ll && r == rr){
     77         f(v, ll, rr, i);
     78         return ;
     79     }
     80     push_down(i, ll, rr);
     81     if(r <= md) update(l, r, v, lson);
     82     else if(l > md) update(l, r, v, rson);
     83     else update(l, md, v, lson), update(md + 1, r, v, rson);
     84     push_up(i);
     85 }
     86 LL query(int l, int r, int p, int v, int ll, int rr, int i){
     87     if(l == ll && r == rr){
     88         LL ret = 0, tmp = 1;
     89         for(int j = v; j >= 0; --j){
     90             //printf("%lld
    ", sum[i][j]);
     91             ret = (ret + sum[i][j] * c[v][j] % mod * tmp % mod + mod) % mod;
     92             tmp = tmp * (1 - p) % mod;
     93            // printf("%lld
    ", ret);
     94         }
     95         return ret;
     96     }
     97     push_down(i, ll, rr);
     98     LL ret;
     99     if(r <= md) ret = query(l, r, p, v, lson);
    100     else if(l > md) ret = query(l, r, p, v, rson);
    101     else ret = (query(l, md, p, v, lson) + query(md + 1, r, p, v, rson)) % mod;
    102     push_up(i);
    103     return ret;
    104 }
    105 int main(){
    106     init();
    107     int n, m;
    108     scanf("%d%d", &n, &m);
    109     build(1, n, 1);
    110     while(m--){
    111         int L, R, k;
    112         char ch[5];
    113         scanf("%s%d%d%d", &ch, &L, &R, &k);
    114         if(ch[0] == '=')
    115             update(L, R, k, 1, n, 1);
    116         else printf("%I64d
    ", query(L, R, L, k, 1, n, 1));
    117     }
    118     return 0;
    119 }
    View Code

    hdu 4417 Super Mario

    长为n的序列,q次询问,每次输出[l, r]内小于h的个数

    做法:离散化,将询问排序。线段树搞一下。(将初始序列排序,询问再排序,用树状数组也能搞,而且更快)

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cmath>
      4 #include<string>
      5 #include<cstring>
      6 #include<algorithm>
      7 #include<set>
      8 #include<queue>
      9 #include <bitset>
     10 using namespace std;
     11 
     12 #define ULL unsigned long long
     13 #define eps 1e-9
     14 #define inf 0x3f3f3f3f
     15 #define ls i << 1
     16 #define rs ls | 1
     17 #define md ((ll + rr) >> 1)
     18 #define lson ll, md, ls
     19 #define rson md + 1, rr, rs
     20 #define LL long long
     21 #define N 100100
     22 #define M 200200
     23 #define mod 2015
     24 #define MP make_pair
     25 #define PB push_back
     26 
     27 int sum[N<<4];
     28 void update(int p, int ll, int rr, int i){
     29     if(ll == rr){
     30         sum[i]++;
     31         return ;
     32     }
     33     if(p <= md) update(p, lson);
     34     else update(p, rson);
     35     sum[i] = sum[ls] + sum[rs];
     36 }
     37 int query(int l, int r, int ll, int rr, int i){
     38     if(l == ll && r == rr)
     39         return sum[i];
     40     if(r <= md) return query(l, r, lson);
     41     if(l > md) return query(l, r, rson);
     42     return query(l, md, lson) + query(md + 1, r, rson);
     43 }
     44 struct node{
     45     int p, h, id;
     46     node(int p = 0, int h = 0, int id = 0) : p(p), h(h), id(id) {}
     47     bool operator < (const node &b) const{
     48         return p < b.p;
     49     }
     50 }L[N], R[N];
     51 int cnt, a[N], b[N<<1], qL[N], qR[N];
     52 int Hash(int v){
     53     return (int)(lower_bound(b + 1, b + 1 + cnt, v) - b);
     54 }
     55 void debug(){
     56     for(int i = 1; i <= cnt; ++i)
     57         printf("%d ", b[i]);
     58     cout << endl;
     59 }
     60 int main(){
     61     int cas, kk = 0;
     62     scanf("%d", &cas);
     63     while(cas--){
     64         int n, m;
     65         scanf("%d%d", &n, &m);
     66         cnt = 0;
     67         for(int i = 1; i <= n; ++i){
     68             scanf("%d", &a[i]);
     69             b[++cnt] = a[i];
     70         }
     71         for(int i = 1; i <= m; ++i){
     72             int l, r, h;
     73             scanf("%d%d%d", &l, &r, &h);
     74             l++, r++;
     75             L[i] = node(l, h, i);
     76             R[i] = node(r, h, i);
     77             b[++cnt] = h;
     78         }
     79         sort(b + 1, b + 1 + cnt);
     80         cnt = unique(b + 1, b + 1 + cnt) - b - 1;
     81         sort(L + 1, L + 1 + m);
     82         sort(R + 1, R + 1 + m);
     83     //    debug();
     84         memset(sum, 0, sizeof sum);
     85         int j = 1, k = 1;
     86         for(int i = 1; i <= n; ++i){
     87             while(L[j].p == i){
     88                 int p = Hash(L[j].h);
     89             //    printf("%d
    ", p);
     90                 qL[L[j].id] = query(1, p, 1, cnt, 1);
     91                 j++;
     92             }
     93             int p = Hash(a[i]);
     94             update(p, 1, cnt, 1);
     95             while(R[k].p == i){
     96                 int p = Hash(R[k].h);
     97                 qR[R[k].id] = query(1, p, 1, cnt, 1);
     98                 k++;
     99             }
    100         }
    101         printf("Case %d:
    ", ++kk);
    102         for(int i = 1; i <= m; ++i){
    103             printf("%d
    ", qR[i] - qL[i]);
    104         }
    105     }
    106     return 0;
    107 }
    View Code
  • 相关阅读:
    后端开发应该掌握的 Redis 基础
    Code Review有什么好处?
    对不起,你那不叫努力,叫重复劳动
    老鸟程序员才知道的40个小技巧
    单例模式基础笔记
    最受IT公司欢迎的50款开源软件
    硬件:关于路由器、交换机、宽带猫的几个问题
    硬件:宽带猫(光猫)的基础知识
    python selenium模块使用出错解决,Message: ‘geckodriver’ executable needs to be in PATH
    python+selenium如何定位页面的元素,的几种定位元素的方法。
  • 原文地址:https://www.cnblogs.com/LJ-blog/p/4749242.html
Copyright © 2011-2022 走看看