BZOJ 2821 分块统计
传说中的主席树可以做!ym zxr神犇~
此题目同:http://www.cnblogs.com/proverbs/archive/2013/01/17/2865123.html
View Code
1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 #include <cstdlib> 5 #include <algorithm> 6 #include <cmath> 7 #include <ctime> 8 9 #define N 100500 10 #define M 2000 11 12 using namespace std; 13 14 int c[N],lt[N],rt[N],qz[N]; 15 int tot,sz; 16 int st[N],ed[N]; 17 int cs[N],val[N]; 18 int d[M][M]; 19 int q[N]; 20 int n,pp,m,bx,by; 21 22 inline void prev() 23 { 24 tot=(int)sqrt(1.0*n); sz=n/tot; 25 for(int i=1;i<=tot;i++) 26 { 27 st[i]=ed[i-1]+1; 28 ed[i]=st[i]+sz-1; 29 } 30 if(ed[tot]<n) 31 { 32 ++tot; 33 st[tot]=ed[tot-1]+1; 34 ed[tot]=n; 35 } 36 for(int i=1;i<=tot;i++) 37 { 38 int cnt=0; 39 memset(cs,0,sizeof cs); 40 for(int j=i;j<=tot;j++) 41 { 42 for(int k=st[j];k<=ed[j];k++) 43 { 44 cs[val[k]]++; 45 if(!(cs[val[k]]&1)) cnt++; 46 else if(cs[val[k]]!=1) cnt--; 47 } 48 d[i][j]=cnt; 49 } 50 } 51 } 52 53 inline void read() 54 { 55 memset(cs,0,sizeof cs); 56 scanf("%d%d%d",&n,&pp,&m); 57 for(int i=1,a;i<=n;i++) 58 { 59 scanf("%d",&val[i]); 60 cs[val[i]]++; 61 } 62 63 for(int i=1;i<=pp;i++) 64 { 65 qz[i]=qz[i-1]+cs[i]; 66 lt[i]=qz[i-1]+1;rt[i]=qz[i-1]; 67 } 68 for(int i=1;i<=n;i++) 69 c[++rt[val[i]]]=i; 70 prev(); 71 } 72 73 inline int force(int x,int y) 74 { 75 for(int i=x;i<=y;i++) cs[val[i]]=0; 76 int cnt=0; 77 for(int i=x;i<=y;i++) 78 { 79 cs[val[i]]++; 80 if(!(cs[val[i]]&1)) cnt++; 81 else if(cs[val[i]]!=1) cnt--; 82 } 83 return cnt; 84 } 85 86 inline int getcnt(int ll,int rr,int x) 87 { 88 return upper_bound(c+rt[x-1]+1,c+rt[x]+1,rr)-lower_bound(c+rt[x-1]+1,c+rt[x]+1,ll); 89 } 90 91 inline int getans(int x,int y) 92 { 93 bx=(x+sz-1)/sz; 94 by=(y+sz-1)/sz; 95 if(bx==by||bx+1==by) return force(x,y); 96 int h=0,ans=0; 97 98 for(int i=x;i<=ed[bx];i++) cs[val[i]] = 0; 99 for(int i=st[by];i<=y;i++) cs[val[i]] = 0; 100 101 for(int i=x;i<=ed[bx];i++) 102 { 103 cs[val[i]]++; 104 if(cs[val[i]]==1) q[++h]=val[i]; 105 } 106 for(int i=st[by];i<=y;i++) 107 { 108 cs[val[i]]++; 109 if(cs[val[i]]==1) q[++h]=val[i]; 110 } 111 bx++; by--; 112 ans=d[bx][by]; 113 for(int i=1,bnt;i<=h;i++) 114 { 115 bnt=getcnt(st[bx],ed[by],q[i]); 116 if(cs[q[i]]&1) 117 { 118 if(bnt&1) ans++; 119 else if(bnt!=0) ans--; 120 } 121 else 122 { 123 if(bnt==0) ans++; 124 } 125 } 126 return ans; 127 } 128 129 inline void go() 130 { 131 int ans=0; 132 for(int i=1,a,b;i<=m;i++) 133 { 134 scanf("%d%d",&a,&b); 135 a=(a+ans)%n+1; 136 b=(b+ans)%n+1; 137 if(a>b) swap(a,b); 138 ans=getans(a,b); 139 printf("%d\n",ans); 140 } 141 } 142 143 int main() 144 { 145 read(); 146 go(); 147 return 0; 148 }
没有人能阻止我前进的步伐,除了我自己!