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 }