1.统计颜色,或运算的运用
2.区间第k大数
3.一个很经典的题
5.求区间相等数字的个数
6.RMQ模板题,区间最大值和最小值的差
1.很好的思路,用或运算来避免左右儿子树总相同颜色的情况。由于
T颜色种类最多30种,__int64 足够用了。
注意初始化就行。
5.关键是写对make_up()这个函数,向上更新需要考虑的问题。经典题型。
1001
1 /* 2 3 求区间[l,r]中,颜色的总类。 4 如何避免重复?----或运算。 5 6 */ 7 8 #include<iostream> 9 #include<cstdio> 10 #include<cstdlib> 11 #include<algorithm> 12 #define HH 1 13 using namespace std; 14 15 16 struct node 17 { 18 int l; 19 int r; 20 int color; 21 __int64 num; 22 }f[100003*8]; 23 24 25 void build(int l,int r,int n) 26 { 27 int mid=(l+r)/2; 28 f[n].l=l; 29 f[n].r=r; 30 f[n].color=0; 31 f[n].num=1<<1; 32 if(l==r) 33 return ; 34 build(l,mid,n*2); 35 build(mid+1,r,n*2+1); 36 } 37 38 void make_down(int n) 39 { 40 f[n*2].color=f[n*2+1].color=HH; 41 42 f[n*2].num=f[n*2+1].num=f[n].num; 43 44 f[n].color=0; 45 f[n].num=0; 46 } 47 48 void update(int l,int r,int num,int n) 49 { 50 int mid=(f[n].l+f[n].r)/2; 51 52 if(f[n].l==l && f[n].r==r) 53 { 54 f[n].color=HH; 55 f[n].num=1<<num; 56 return; 57 } 58 if(f[n].color==HH) 59 make_down(n); 60 if(mid>=r) 61 update(l,r,num,n*2); 62 else if(mid<l) 63 update(l,r,num,n*2+1); 64 else 65 { 66 update(l,mid,num,n*2); 67 update(mid+1,r,num,n*2+1); 68 } 69 f[n].num=f[n*2].num|f[n*2+1].num; 70 } 71 72 __int64 query(int l,int r,int n) 73 { 74 int mid=(f[n].l+f[n].r)/2; 75 __int64 cur=0; 76 if(f[n].l==l && f[n].r==r) 77 { 78 return f[n].num; 79 } 80 if(f[n].color==HH) 81 make_down(n); 82 if(mid>=r) 83 cur=query(l,r,n*2); 84 else if(mid<l) 85 cur=query(l,r,n*2+1); 86 else 87 { 88 cur=query(l,mid,n*2)|query(mid+1,r,n*2+1); 89 } 90 f[n].num=f[n*2].num|f[n*2+1].num; 91 return cur; 92 93 } 94 95 int Get_num(__int64 num) //得到1的个数 很优化的算法。 96 { 97 int count=0; 98 while(num) 99 { 100 ++count; 101 num=(num-1)# 102 } 103 return count; 104 } 105 106 void make_ini(int L,int T,int O) 107 { 108 int A,B,num,hxl; 109 __int64 tmp; 110 char a[5]; 111 while(O--) 112 { 113 scanf("%s",a); 114 if(a[0]=='C') 115 { 116 scanf("%d%d%d",&A,&B,&num); 117 if(A>B) 118 { 119 hxl=A; 120 A=B; 121 B=hxl; 122 } 123 if(num<=T) 124 update(A,B,num,1); 125 } 126 else if(a[0]=='P') 127 { 128 scanf("%d%d",&A,&B); 129 if(A>B) 130 { 131 hxl=A; 132 A=B; 133 B=hxl; 134 } 135 tmp=query(A,B,1); 136 printf("%d\n",Get_num(tmp)); 137 } 138 } 139 } 140 141 int main() 142 { 143 int L,T,O; 144 while(scanf("%d%d%d",&L,&T,&O)>0) 145 { 146 build(1,L,1); 147 make_ini(L,T,O); 148 } 149 return 0; 150 }
1002
1 /* 2 第k小的数 3 4 */ 5 6 #include<iostream> 7 #include<cstdio> 8 #include<cstdlib> 9 #include<cstring> 10 #include<algorithm> 11 #define NN 100010 12 using namespace std; 13 14 15 int toleft[30][NN]; 16 int Tree[30][NN]; 17 int Sort[NN]; 18 19 20 void build(int l,int r,int dep) 21 { 22 int mid=(l+r)/2,sum=mid-l+1,lpos,rpos,i; 23 if(l==r) return ; 24 for(i=l;i<=r;i++) 25 if(Tree[dep][i]<Sort[mid]) sum--; 26 lpos=l; 27 rpos=mid+1; 28 for(i=l;i<=r;i++) 29 { 30 if(Tree[dep][i]<Sort[mid]) 31 { 32 Tree[dep+1][lpos++]=Tree[dep][i]; 33 } 34 else if(Tree[dep][i]==Sort[mid] && sum>0) 35 { 36 Tree[dep+1][lpos++]=Tree[dep][i]; 37 sum--; 38 } 39 else 40 { 41 Tree[dep+1][rpos++]=Tree[dep][i]; 42 } 43 toleft[dep][i]=toleft[dep][l-1]+lpos-l; 44 } 45 build(l,mid,dep+1); 46 build(mid+1,r,dep+1); 47 } 48 49 int query(int L,int R,int l,int r,int k,int dep) 50 { 51 int mid=(L+R)/2,newl,newr,cur; 52 if(l==r) return Tree[dep][l]; 53 cur=toleft[dep][r]-toleft[dep][l-1]; 54 if(cur>=k) 55 { 56 newl=L+toleft[dep][l-1]-toleft[dep][L-1]; 57 newr=newl+cur-1; 58 return query(L,mid,newl,newr,k,dep+1); 59 } 60 else 61 { 62 newr=r+(toleft[dep][R]-toleft[dep][r]); 63 newl=newr-(r-l-cur); 64 return query(mid+1,R,newl,newr,k-cur,dep+1); 65 } 66 } 67 68 void make_ini(int N,int M) 69 { 70 int l,r,k; 71 while(M--) 72 { 73 scanf("%d%d%d",&l,&r,&k); 74 printf("%d\n",query(1,N,l,r,k,0)); 75 } 76 } 77 78 int main() 79 { 80 int N,M,i; 81 while(scanf("%d%d",&N,&M)>0) 82 { 83 for(i=1;i<=N;i++) 84 { 85 scanf("%d",&Tree[0][i]); 86 Sort[i]=Tree[0][i]; 87 } 88 sort(Sort+1,Sort+1+N); 89 build(1,N,0); 90 make_ini(N,M); 91 } 92 return 0; 93 }
1003
1 #include<cstdio> 2 #include<iostream> 3 #include<cstdlib> 4 #define HH 1 //纯色 5 using namespace std; 6 7 struct st 8 { 9 __int64 l; 10 __int64 r; 11 __int64 num; 12 __int64 color; 13 __int64 max; 14 }f[100003*4]; 15 __int64 date[100003]; 16 17 void build(__int64 l,__int64 r,__int64 n) 18 { 19 __int64 mid=(l+r)/2; 20 f[n].l=l; 21 f[n].r=r; 22 f[n].color=0; 23 f[n].num=0; 24 if(l==r) 25 { 26 f[n].max=date[l]; 27 return; 28 } 29 build(l,mid,n*2); 30 build(mid+1,r,n*2+1); 31 f[n].max=f[n*2].max+f[n*2+1].max; 32 } 33 34 void make_down(__int64 n) 35 { 36 37 f[n*2].num+=f[n].num; 38 f[n*2].color=HH; 39 f[n*2].max+=f[n].num*(f[n*2].r-f[n*2].l+1); 40 41 f[n*2+1].num+=f[n].num; 42 f[n*2+1].color=HH; 43 f[n*2+1].max+=f[n].num*(f[n*2+1].r-f[n*2+1].l+1); 44 45 f[n].color=0;f[n].num=0; 46 } 47 48 void update(__int64 l,__int64 r,__int64 num,__int64 n) 49 { 50 __int64 mid=(f[n].l+f[n].r)/2; 51 if(f[n].l==l && f[n].r==r) 52 { 53 f[n].num+=num; 54 f[n].max+=num*(f[n].r-f[n].l+1); 55 f[n].color=HH; 56 return ; 57 } 58 if(f[n].color==HH) 59 make_down(n); 60 if(mid>=r) 61 update(l,r,num,n*2); 62 else if(mid<l) 63 update(l,r,num,n*2+1); 64 else 65 { 66 update(l,mid,num,n*2); 67 update(mid+1,r,num,n*2+1); 68 } 69 f[n].max=f[n*2].max+f[n*2+1].max; 70 } 71 72 __int64 query(__int64 l,__int64 r,__int64 n) 73 { 74 __int64 mid=(f[n].l+f[n].r)/2; 75 __int64 cur=0; 76 if(f[n].l==l && f[n].r==r) 77 { 78 return f[n].max; 79 } 80 if(f[n].color==HH) 81 make_down(n); 82 if(mid>=r) 83 cur= query(l,r,n*2); 84 else if(mid<l) 85 cur= query(l,r,n*2+1); 86 else 87 { 88 cur+= query(l,mid,n*2); 89 cur+=query(mid+1,r,n*2+1); 90 } 91 f[n].max=f[n*2].max+f[n*2+1].max; 92 return cur; 93 } 94 95 int main() 96 { 97 __int64 n,q,i,l,r,num; 98 char a[5]; 99 while(scanf("%I64d%I64d",&n,&q)>0) 100 { 101 for(i=1;i<=n;i++) 102 scanf("%I64d",&date[i]); 103 build(1,n,1); 104 while(q--) 105 { 106 scanf("%s",a); 107 if(a[0]=='Q') 108 { 109 scanf("%I64d%I64d",&l,&r); 110 printf("%I64d\n",query(l,r,1)); 111 } 112 else if(a[0]=='C') 113 { 114 scanf("%I64d%I64d%I64d",&l,&r,&num); 115 update(l,r,num,1); 116 } 117 } 118 } 119 return 0; 120 }
1005
1 /* 2 3 求区间[l,r]中,相等数字的最大个数 4 试一试能不能A。 5 6 */ 7 8 #include<iostream> 9 #include<cstdio> 10 #include<cstdlib> 11 #include<algorithm> 12 using namespace std; 13 14 15 16 struct node 17 { 18 int l; 19 int r; 20 int lmax,rmax,max; 21 int lnum,rnum; 22 int len; 23 }f[100003*4]; 24 int Date[100003]; 25 26 int hmax(int x,int y) 27 { 28 return x>y? x: y; 29 } 30 31 int hmin(int x,int y) 32 { 33 return x>y? y:x; 34 } 35 36 void make_up(node *father,node *l_child,node *r_child) 37 { 38 father->lnum=l_child->lnum; 39 father->rnum=r_child->rnum; 40 if(l_child->rnum!=r_child->lnum) 41 { 42 father->lmax=l_child->lmax; 43 father->rmax=r_child->rmax; 44 father->max=hmax(hmax(father->lmax,father->rmax), 45 hmax(l_child->max,r_child->max)); 46 } 47 else 48 { 49 father->lmax=(l_child->lmax==l_child->len)? l_child->lmax+r_child->lmax:l_child->lmax; 50 father->rmax=(r_child->rmax==r_child->len)? r_child->rmax+l_child->rmax:r_child->rmax; 51 father->max= hmax(hmax(father->lmax,father->rmax), 52 hmax(l_child->max, 53 hmax(r_child->max,l_child->rmax+r_child->lmax))); 54 } 55 } 56 57 void build(int l,int r,int n) 58 { 59 int mid=(l+r)/2; 60 f[n].l=l; 61 f[n].r=r; 62 f[n].len=f[n].r-f[n].l+1; 63 if(l==r) 64 { 65 f[n].lnum=Date[l]; 66 f[n].rnum=Date[l]; 67 f[n].lmax=f[n].rmax=f[n].max=1; 68 return ; 69 } 70 build(l,mid,n*2); 71 build(mid+1,r,n*2+1); 72 make_up(&f[n],&f[n*2],&f[n*2+1]); 73 } 74 75 int query(int l,int r,int n) 76 { 77 int mid=(f[n].l+f[n].r)/2,cur=0,now1=0,now2=0; 78 79 if(f[n].l==l && f[n].r==r) 80 { 81 return f[n].max; 82 } 83 if(mid>=r) 84 cur=query(l,r,n*2); 85 else if(mid<l) 86 cur=query(l,r,n*2+1); 87 else 88 { 89 now1=query(l,mid,n*2); 90 now2=query(mid+1,r,n*2+1); 91 if(f[n*2].rnum==f[n*2+1].lnum) 92 { 93 cur=hmax(hmax(now1,now2),hmin(mid-l+1,f[n*2].rmax)+ 94 hmin(r-mid,f[n*2+1].lmax)); 95 } 96 else 97 { 98 cur=hmax(now1,now2); 99 } 100 } 101 return cur; 102 } 103 104 void make_ini(int Q) 105 { 106 int l,r; 107 while(Q--) 108 { 109 scanf("%d%d",&l,&r); 110 printf("%d\n",query(l,r,1)); 111 } 112 } 113 114 int main() 115 { 116 int N,Q,i; 117 while(scanf("%d",&N)>0) 118 { 119 if(N==0)break; 120 scanf("%d",&Q); 121 for(i=1;i<=N;i++) 122 scanf("%d",&Date[i]); 123 build(1,N,1); 124 make_ini(Q); 125 } 126 }
1006
1 /* 2 求区间[l,r],最大值和最小值的差值。 3 */ 4 5 6 #include<iostream> 7 #include<cstdio> 8 #include<cstdlib> 9 #include<cstring> 10 #include<algorithm> 11 #define MAX 1000010 12 using namespace std; 13 14 15 struct node 16 { 17 int l; 18 int r; 19 int min; 20 int max; 21 }f[50003*4]; 22 int Date[50003]; 23 24 25 int hmax(int x,int y) 26 { 27 return x>y? x:y; 28 } 29 30 int hmin(int x,int y) 31 { 32 return x>y? y:x; 33 } 34 35 void build(int l,int r,int n) 36 { 37 int mid=(l+r)/2; 38 f[n].l=l; 39 f[n].r=r; 40 if(l==r) 41 { 42 f[n].max=Date[l]; 43 f[n].min=Date[l]; 44 return; 45 } 46 build(l,mid,n*2); 47 build(mid+1,r,n*2+1); 48 f[n].max=hmax(f[n*2].max,f[n*2+1].max); 49 f[n].min=hmin(f[n*2].min,f[n*2+1].min); 50 } 51 52 void query(int l,int r,int *a,int *b,int n) 53 { 54 int mid=(f[n].l+f[n].r)/2; 55 if(f[n].l==l && f[n].r==r) 56 { 57 if(f[n].min<*a) 58 *a=f[n].min; 59 if(f[n].max>*b) 60 *b=f[n].max; 61 return; 62 } 63 if(mid>=r) 64 query(l,r,a,b,n*2); 65 else if(mid<l) 66 query(l,r,a,b,n*2+1); 67 else 68 { 69 query(l,mid,a,b,n*2); 70 query(mid+1,r,a,b,n*2+1); 71 } 72 } 73 74 int main() 75 { 76 int N,Q,i; 77 int a,b,l,r; 78 while(scanf("%d%d",&N,&Q)>0) 79 { 80 for(i=1;i<=N;i++) 81 scanf("%d",&Date[i]); 82 build(1,N,1); 83 while(Q--) 84 { 85 scanf("%d%d",&l,&r); 86 a=MAX;b=-1; 87 query(l,r,&a,&b,1); 88 printf("%d\n",b-a); 89 } 90 } 91 return 0; 92 }