2019 ICPC Asia Yinchuan Regional G. Pot!!(线段树维护区间因子个数)
https://nanti.jisuanke.com/t/42387
x的数据范围只有2~10,也就是说x只可能含2、3、5、7这四个因子,那么就可以用等价于4棵线段树的数据结构去维护区间4个素因子的信息了。
用线段树维护区间Pot(ai)的最大值,每次区间修改,只需使区间修改2、3、5、7这四个素因子个数,最大值查询也只需查询2、3、5、7四个素因子的max值。
注意用scanf和printf输入输出,否则cin、cout T到自闭。
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn = 1e5+5; 4 int n,q; 5 struct node{ 6 int l,r; 7 int lz[5]; 8 int m[10]; 9 }t[maxn<<2]; 10 void build(int l,int r,int p){ 11 t[p].l = l,t[p].r = r; 12 if(l == r) { 13 return; 14 } 15 int mid = (l+r)>>1; 16 build(l,mid,p<<1); 17 build(mid+1,r,p<<1|1); 18 // t[p].Max = max(t[p*2].Max,t[p*2+1].Max); 19 } 20 void pushdown(int k){ 21 t[k<<1].lz[0]+=t[k].lz[0] ; 22 t[k<<1|1].lz[0] +=t[k].lz[0] ; 23 24 t[k<<1].lz[1]+=t[k].lz[1] ; 25 t[k<<1|1].lz[1] +=t[k].lz[1] ; 26 27 t[k<<1].lz[2]+=t[k].lz[2] ; 28 t[k<<1|1].lz[2] +=t[k].lz[2] ; 29 30 t[k<<1].lz[3]+=t[k].lz[3] ; 31 t[k<<1|1].lz[3] +=t[k].lz[3] ; 32 // 33 t[k<<1].m[2] +=t[k].lz[0]; 34 // t[k*2].Max = max(t[k*2].Max ,t[k*2].m[2]); 35 36 t[k<<1|1].m[2] +=t[k].lz[0] ; 37 // t[k*2+1].Max = max(t[k*2+1].Max ,t[k*2+1].m[2]); 38 39 t[k<<1].m[3] +=t[k].lz[1] ; 40 // t[k*2].Max = max(t[k*2].Max,t[k*2].m[3]); 41 42 t[k<<1|1].m[3] +=t[k].lz[1] ; 43 // t[k*2+1].Max = max(t[k*2+1].Max ,t[k*2+1].m[3]); 44 45 t[k<<1].m[5] +=t[k].lz[2] ; 46 // t[k*2].Max = max(t[k*2].Max ,t[k*2].m[5]); 47 48 t[k<<1|1].m[5] +=t[k].lz[2] ; 49 // t[k*2+1].Max = max(t[k*2+1].Max ,t[k*2+1].m[5]); 50 51 t[k<<1].m[7] +=t[k].lz[3] ; 52 // t[k*2].Max = max(t[k*2].Max ,t[k*2].m[7]); 53 54 t[k<<1|1].m[7] +=t[k].lz[3] ; 55 // t[k*2+1].Max = max(t[k*2+1].Max ,t[k*2+1].m[7]); 56 // 57 t[k].lz[0] = 0,t[k].lz[1] = 0,t[k].lz[2] = 0,t[k].lz[3] = 0; 58 } 59 void upd(int L,int R,int p,int v){ 60 if(t[p].l >= L && t[p].r <= R){ 61 if(v == 2) t[p].lz[0]+=1,t[p].m[2]+=1; 62 if(v == 3) t[p].lz[1]+=1,t[p].m[3]+=1; 63 if(v == 4) t[p].lz[0]+=2,t[p].m[2]+=2; 64 if(v == 5) t[p].lz[2]+=1,t[p].m[5]+=1; 65 if(v == 6) { 66 t[p].lz[0]+=1,t[p].m[2]+=1; 67 t[p].lz[1]+=1,t[p].m[3]+=1; 68 } 69 if(v == 7){ 70 t[p].lz[3]+=1,t[p].m[7]+=1; 71 } 72 if(v == 8) t[p].lz[0]+=3,t[p].m[2]+=3; 73 if(v == 9) t[p].lz[1]+=2,t[p].m[3]+=2; 74 if(v == 10) { 75 t[p].lz[0]+=1,t[p].m[2]+=1; 76 t[p].lz[2]+=1,t[p].m[5]+=1; 77 } 78 return; 79 } 80 if(t[p].lz[0] !=0 ||t[p].lz[1]!=0||t[p].lz[2]!=0 ||t[p].lz[3]!=0) pushdown(p); 81 int mid = (t[p].l + t[p].r )>>1; 82 if(R<=mid) upd(L,R,p<<1,v); 83 else if(L>mid) upd(L,R,p<<1|1,v); 84 else{ 85 upd(L,mid,p<<1,v); 86 upd(mid+1,R,p<<1|1,v); 87 } 88 t[p].m[2] = max(t[p<<1].m[2],t[p<<1|1].m[2]); 89 t[p].m[3] = max(t[p<<1].m[3],t[p<<1|1].m[3]); 90 t[p].m[5] = max(t[p<<1].m[5],t[p<<1|1].m[5]); 91 t[p].m[7] = max(t[p<<1].m[7],t[p<<1|1].m[7]); 92 return; 93 } 94 int query(int p,int L,int R){ 95 if(t[p].l >= L && t[p].r <= R){ 96 int res = 0; 97 res = max(res,t[p].m[2]); 98 res = max(res,t[p].m[3]); 99 res = max(res,t[p].m[5]); 100 res = max(res,t[p].m[7]); 101 return res; 102 } 103 if(t[p].lz[0] !=0 ||t[p].lz[1]!=0||t[p].lz[2]!=0 ||t[p].lz[3]!=0) pushdown(p); 104 int mid = (t[p].l + t[p].r )>>1; 105 if(R<=mid) return query(p<<1,L,R); 106 else if(L>mid) return query(p<<1|1,L,R); 107 else{ 108 return max( query(p<<1,L,mid),query(p<<1|1,mid+1,R) ); 109 } 110 111 } 112 int main(){ 113 scanf("%d%d",&n,&q); 114 build(1,n,1); 115 while(q--){ 116 char s[10]; 117 scanf("%s",s); 118 if(s[1] == 'U'){ 119 int l,r,x; 120 scanf("%d%d%d",&l,&r,&x); 121 upd(l,r,1,x); 122 } 123 else{ 124 int l,r; 125 scanf("%d%d",&l,&r); 126 int ans = query(1,l,r); 127 printf("ANSWER %d\n",ans); 128 } 129 } 130 return 0; 131 } 132 /* 133 5 6 134 MULTIPLY 1 3 3 135 MULTIPLY 3 3 3 136 MULTIPLY 2 3 3 137 MAX 1 3 138 MULTIPLY 1 1 9 139 MAX 4 5 140 */