BZOJ_3110

值域线段树套上一颗区间线段树。

查询的时候二分找。最后树套树的空间一定要好好算算。。

  1 #include <cstdio>
  2 #include <iostream>
  3 #include <algorithm>
  4 #include <cstring>
  5 using namespace std;
  6 const int N = 50000;
  7 int n,m,t1,t2;
  8 struct tree1 {
  9     tree1* lson;
 10     tree1* rson;
 11     int cnt,lazy;
 12     tree1() {
 13         lson = rson = NULL;
 14         cnt = lazy = 0;
 15     }
 16 }dizhi1[N*600];
 17 struct tree2 {
 18     tree2* lson;
 19     tree2* rson;
 20     tree1* on_tree;
 21     tree2() {
 22         lson = rson = NULL;
 23         on_tree = NULL;
 24     }
 25 }*root,dizhi2[N*4];
 26 inline void push_down(tree1* tree,int l,int r) {
 27     if(tree->lazy) {
 28         int mid = (l+r)>>1;
 29         if(tree->lson==NULL) tree->lson = &dizhi1[++t1];
 30         if(tree->rson==NULL) tree->rson = &dizhi1[++t1];
 31         tree->lson->cnt += (mid-l+1)*tree->lazy;
 32         tree->rson->cnt += (r-mid)*tree->lazy;
 33         tree->lson->lazy += tree->lazy;
 34         tree->rson->lazy += tree->lazy;
 35         tree->lazy = 0;
 36     }
 37 }
 38 inline void modify2(tree1* tree,int l,int r,int x,int y) {
 39     if(l!=r) push_down(tree,l,r);
 40     if(x<=l && r<=y) {
 41         tree->cnt += (r-l+1);
 42         tree->lazy = 1;
 43         return ;
 44     }
 45     int mid = (l+r)>>1;
 46     if(!(y<l||mid<x)) {
 47         if(tree->lson==NULL) tree->lson = &dizhi1[++t1];
 48         modify2(tree->lson,l,mid,x,y);
 49     }
 50     if(!(y<mid+1||r<x)) {
 51         if(tree->rson==NULL) tree->rson = &dizhi1[++t1];
 52         modify2(tree->rson,mid+1,r,x,y);
 53     }
 54     tree->cnt = 0;
 55     if(tree->lson!=NULL) tree->cnt += tree->lson->cnt;
 56     if(tree->rson!=NULL) tree->cnt += tree->rson->cnt;
 57 }
 58 inline void modify(tree2* tree,int l,int r,int pos,int x,int y) {
 59     modify2(tree->on_tree,1,n,x,y);
 60     if(l==r) return;
 61     int mid = (l+r)>>1;
 62     if(pos <= mid) modify(tree->lson,l,mid,pos,x,y);
 63     else modify(tree->rson,mid+1,r,pos,x,y);
 64 }
 65 inline int query2(tree1* tree,int l,int r,int x,int y) {
 66     if(l!=r) push_down(tree,l,r);
 67     if(x<=l && r<=y) return tree->cnt;
 68     int mid = (l+r)>>1;
 69     int q1 = 0,q2 = 0;
 70     if((!(y<l||mid<x)) && (tree->lson!=NULL)) q1 = query2(tree->lson,l,mid,x,y);
 71     if((!(y<mid+1||r<x)) && (tree->rson!=NULL)) q2 = query2(tree->rson,mid+1,r,x,y);
 72     return (q1+q2);
 73 }
 74 inline int query(tree2* tree,int l,int r,int x,int y,int c) {
 75     if(l==r) return l;
 76     int mid = (l+r)>>1;
 77     int q1 = query2(tree->rson->on_tree,1,n,x,y);
 78     if(q1>=c) return query(tree->rson,mid+1,r,x,y,c);
 79     else return query(tree->lson,l,mid,x,y,c-q1);
 80 }
 81 inline void build(tree2* tree,int l,int r) {
 82     tree->on_tree = &dizhi1[++t1];
 83     if(l==r) return;
 84     int mid = (l+r)>>1;
 85     tree->lson = &dizhi2[++t2];
 86     tree->rson = &dizhi2[++t2];
 87     build(tree->lson,l,mid);
 88     build(tree->rson,mid+1,r);
 89 }
 90 int main() {
 91     scanf("%d%d",&n,&m);
 92     root = &dizhi2[++t2];
 93     build(root,1,n);
 94     for(int i = 1 ; i <= m ; ++i) {
 95         int k,a,b,c;
 96         scanf("%d%d%d%d",&k,&a,&b,&c);
 97         if(k==1) modify(root,1,n,c,a,b);
 98         else printf("%d\n",query(root,1,n,a,b,c));
 99     }
100 }
View Code

 

posted @ 2015-12-28 10:48  443singer  阅读(112)  评论(0编辑  收藏  举报