2821: 作诗(Poetize)
Time Limit: 50 Sec Memory Limit: 128 MBSubmit: 1078 Solved: 348
[Submit][Status]
Description
神犇SJY虐完HEOI之后给傻×LYD出了一题:
SHY是T国的公主,平时的一大爱好是作诗。
由于时间紧迫,SHY作完诗之后还要虐OI,于是SHY找来一篇长度为N的文章,阅读M次,每次只阅读其中连续的一段[l,r],从这一段中选出一些汉字构成诗。因为SHY喜欢对偶,所以SHY规定最后选出的每个汉字都必须在[l,r]里出现了正偶数次。而且SHY认为选出的汉字的种类数(两个一样的汉字称为同一种)越多越好(为了拿到更多的素材!)。于是SHY请LYD安排选法。
LYD这种傻×当然不会了,于是向你请教……
问题简述:N个数,M组询问,每次问[l,r]中有多少个数出现正偶数次。
Input
输入第一行三个整数n、c以及m。表示文章字数、汉字的种类数、要选择M次。
第二行有n个整数,每个数Ai在[1, c]间,代表一个编码为Ai的汉字。
接下来m行每行两个整数l和r,设上一个询问的答案为ans(第一个询问时ans=0),令L=(l+ans)mod n+1, R=(r+ans)mod n+1,若L>R,交换L和R,则本次询问为[L,R]。
Output
输出共m行,每行一个整数,第i个数表示SHY第i次能选出的汉字的最多种类数。
Sample Input
5 3 5
1 2 2 3 1
0 4
1 2
2 2
2 3
3 5
1 2 2 3 1
0 4
1 2
2 2
2 3
3 5
Sample Output
2
0
0
0
1
0
0
0
1
HINT
对于100%的数据,1<=n,c,m<=10^5
Source
挖个坑,以后来填。。。
本来用这题来练分块的,结果完全被二分坑到了QAQ。。。TLE...哪天有空A了这题
我的代码:
1.二分自己yy的
1 {$inline on} 2 const maxn=100000+100; 3 type node=record 4 p,v:longint; 5 end; 6 var b:array[0..maxn] of node; 7 a,belong,v,head,tail:array[0..maxn] of longint; 8 mark:array[0..maxn] of boolean; 9 f:array[0..400,0..400] of longint; 10 l,r:array[0..400] of longint; 11 i,j,n,m,tot,ans,ll,rr,block,cnt,x:longint; 12 function max(x,y:longint):longint;inline; 13 begin 14 if x>y then exit(x) else exit(y); 15 end; 16 procedure swap(var x,y:longint);inline; 17 var t:longint; 18 begin 19 t:=x;x:=y;y:=t; 20 end; 21 22 function cmp(x,y:node):boolean;inline; 23 begin 24 if x.v=y.v then exit(x.p<y.p) else exit(x.v<y.v); 25 end; 26 procedure sort(l,r:longint);inline; 27 var i,j:longint;x,y:node; 28 begin 29 i:=l;j:=r;x:=b[(i+j)>>1]; 30 repeat 31 while cmp(b[i],x) do inc(i); 32 while cmp(x,b[j]) do dec(j); 33 if i<=j then 34 begin 35 y:=b[i];b[i]:=b[j];b[j]:=y; 36 inc(i);dec(j); 37 end; 38 until i>j; 39 if i<r then sort(i,r); 40 if j>l then sort(l,j); 41 end; 42 procedure init; 43 begin 44 readln(n,m,m); 45 for i:=1 to n do 46 begin 47 read(a[i]); 48 b[i].p:=i;b[i].v:=a[i]; 49 end; 50 readln; 51 sort(1,n); 52 block:=trunc(sqrt(n)*ln(n)/ln(2)); 53 cnt:=(n-1) div block+1; 54 for i:=1 to n do belong[i]:=(i-1) div block+1; 55 for i:=1 to cnt do 56 begin 57 l[i]:=(i-1)*block+1;r[i]:=i*block; 58 end; 59 r[cnt]:=n; 60 for i:=1 to n do 61 begin 62 x:=b[i].v; 63 if head[x]=0 then head[x]:=i; 64 tail[x]:=i; 65 end; 66 end; 67 procedure prepare; 68 begin 69 for i:=1 to cnt do 70 begin 71 fillchar(v,sizeof(v),0); 72 tot:=0; 73 for j:=l[i] to r[cnt] do 74 begin 75 inc(v[a[j]]); 76 if (v[a[j]] and 1=1) and (v[a[j]]<>1) then dec(tot) 77 else if v[a[j]] and 1=0 then inc(tot); 78 f[i,belong[j]]:=tot; 79 end; 80 end; 81 end; 82 function findup(z,x:longint):longint;inline; 83 var l,r,mid:longint; 84 begin 85 if x>=b[tail[z]].p then exit(tail[z]); 86 l:=head[z];r:=tail[z]; 87 while l<r do 88 begin 89 mid:=(l+r)>>1; 90 if b[mid].p<x then l:=mid+1 91 else if b[mid].p>x then r:=mid 92 else exit(mid); 93 end; 94 exit(l-1); 95 end; 96 function finddown(z,x:longint):longint;inline; 97 var l,r,mid:longint; 98 begin 99 l:=head[z];r:=tail[z]; 100 while l<r do 101 begin 102 mid:=(l+r)>>1; 103 if b[mid].p<x then l:=mid+1 104 else if b[mid].p>x then r:=mid 105 else exit(mid); 106 end; 107 exit(l); 108 end; 109 110 function find(z,x,y:longint):longint;inline; 111 begin 112 find:=max(findup(z,y)-finddown(z,x)+1,0); 113 end; 114 procedure query(x,y:longint);inline; 115 var i,bx,by,t1,t2,z:longint; 116 begin 117 ans:=0; 118 bx:=belong[x];by:=belong[y]; 119 if by-bx<=1 then 120 begin 121 fillchar(v,sizeof(v),0); 122 for i:=x to y do 123 begin 124 inc(v[a[i]]); 125 if (v[a[i]] and 1=1) and (v[a[i]]<>1) then dec(ans) 126 else if v[a[i]] and 1=0 then inc(ans); 127 end; 128 end 129 else 130 begin 131 fillchar(mark,sizeof(mark),false); 132 ans:=f[bx+1,by-1]; 133 for i:=x to r[bx] do 134 begin 135 z:=a[i];if mark[z] then continue;mark[z]:=true; 136 t1:=find(z,x,y);t2:=find(z,l[bx+1],r[by-1]); 137 if (t1 and 1=1) and (t2 and 1=0) and (t2<>0) then dec(ans) 138 else if (t1 and 1=0) and ((t2 and 1=1) or (t2=0)) then inc(ans); 139 end; 140 for i:=l[by] to y do 141 begin 142 z:=a[i];if mark[z] then continue;mark[z]:=true; 143 t1:=find(z,x,y);t2:=find(z,l[bx+1],r[by-1]); 144 if (t1 and 1=1) and (t2 and 1=0) and (t2<>0) then dec(ans) 145 else if (t1 and 1=0) and ((t2 and 1=1) or (t2=0)) then inc(ans); 146 end; 147 end; 148 end; 149 procedure main; 150 begin 151 ans:=0; 152 for i:=1 to m do 153 begin 154 readln(ll,rr); 155 ll:=(ll+ans) mod n+1;rr:=(rr+ans) mod n+1; 156 if ll>rr then swap(ll,rr); 157 query(ll,rr); 158 writeln(ans); 159 end; 160 end; 161 162 begin 163 assign(input,'input.txt');assign(output,'output.txt'); 164 reset(input);rewrite(output); 165 init; 166 prepare; 167 main; 168 close(input);close(output); 169 end.
2.二分摘抄自hzwer
1 {$inline on} 2 const maxn=100000+100; 3 type node=record 4 p,v:longint; 5 end; 6 var b:array[0..maxn] of node; 7 a,belong,v,head,tail:array[0..maxn] of longint; 8 mark:array[0..maxn] of boolean; 9 f:array[0..400,0..400] of longint; 10 l,r:array[0..400] of longint; 11 i,j,n,m,tot,ans,ll,rr,block,cnt,x:longint; 12 function max(x,y:longint):longint;inline; 13 begin 14 if x>y then exit(x) else exit(y); 15 end; 16 procedure swap(var x,y:longint);inline; 17 var t:longint; 18 begin 19 t:=x;x:=y;y:=t; 20 end; 21 22 function cmp(x,y:node):boolean;inline; 23 begin 24 if x.v=y.v then exit(x.p<y.p) else exit(x.v<y.v); 25 end; 26 procedure sort(l,r:longint);inline; 27 var i,j:longint;x,y:node; 28 begin 29 i:=l;j:=r;x:=b[(i+j)>>1]; 30 repeat 31 while cmp(b[i],x) do inc(i); 32 while cmp(x,b[j]) do dec(j); 33 if i<=j then 34 begin 35 y:=b[i];b[i]:=b[j];b[j]:=y; 36 inc(i);dec(j); 37 end; 38 until i>j; 39 if i<r then sort(i,r); 40 if j>l then sort(l,j); 41 end; 42 procedure init; 43 begin 44 readln(n,m,m); 45 for i:=1 to n do 46 begin 47 read(a[i]); 48 b[i].p:=i;b[i].v:=a[i]; 49 end; 50 readln; 51 sort(1,n); 52 block:=trunc(sqrt(n)*ln(n)/ln(2)); 53 cnt:=(n-1) div block+1; 54 for i:=1 to n do belong[i]:=(i-1) div block+1; 55 for i:=1 to cnt do 56 begin 57 l[i]:=(i-1)*block+1;r[i]:=i*block; 58 end; 59 r[cnt]:=n; 60 for i:=1 to n do 61 begin 62 x:=b[i].v; 63 if head[x]=0 then head[x]:=i; 64 tail[x]:=i; 65 end; 66 end; 67 procedure prepare; 68 begin 69 for i:=1 to cnt do 70 begin 71 fillchar(v,sizeof(v),0); 72 tot:=0; 73 for j:=l[i] to r[cnt] do 74 begin 75 inc(v[a[j]]); 76 if (v[a[j]] and 1=1) and (v[a[j]]<>1) then dec(tot) 77 else if v[a[j]] and 1=0 then inc(tot); 78 f[i,belong[j]]:=tot; 79 end; 80 end; 81 end; 82 function findup(z,x:longint):longint;inline; 83 var l,r,mid,tmp:longint; 84 begin 85 l:=head[z];r:=tail[z];tmp:=0; 86 while l<=r do 87 begin 88 mid:=(l+r)>>1; 89 if b[mid].p>x then l:=mid+1 90 else begin tmp:=mid;r:=mid-1;end; 91 end; 92 exit(tmp); 93 end; 94 function finddown(z,x:longint):longint;inline; 95 var l,r,mid,tmp:longint; 96 begin 97 l:=head[z];r:=tail[z];tmp:=maxlongint; 98 while l<=r do 99 begin 100 mid:=(l+r)>>1; 101 if b[mid].p<x then l:=mid+1 102 else begin tmp:=mid;r:=mid-1;end; 103 end; 104 exit(tmp); 105 end; 106 107 function find(z,x,y:longint):longint;inline; 108 begin 109 find:=max(findup(z,y)-finddown(z,x)+1,0); 110 end; 111 procedure query(x,y:longint);inline; 112 var i,bx,by,t1,t2,z:longint; 113 begin 114 ans:=0; 115 bx:=belong[x];by:=belong[y]; 116 if by-bx<=1 then 117 begin 118 fillchar(v,sizeof(v),0); 119 for i:=x to y do 120 begin 121 inc(v[a[i]]); 122 if (v[a[i]] and 1=1) and (v[a[i]]<>1) then dec(ans) 123 else if v[a[i]] and 1=0 then inc(ans); 124 end; 125 end 126 else 127 begin 128 fillchar(mark,sizeof(mark),false); 129 ans:=f[bx+1,by-1]; 130 for i:=x to r[bx] do 131 begin 132 z:=a[i];if mark[z] then continue;mark[z]:=true; 133 t1:=find(z,x,y);t2:=find(z,l[bx+1],r[by-1]); 134 if (t1 and 1=1) and (t2 and 1=0) and (t2<>0) then dec(ans) 135 else if (t1 and 1=0) and ((t2 and 1=1) or (t2=0)) then inc(ans); 136 end; 137 for i:=l[by] to y do 138 begin 139 z:=a[i];if mark[z] then continue;mark[z]:=true; 140 t1:=find(z,x,y);t2:=find(z,l[bx+1],r[by-1]); 141 if (t1 and 1=1) and (t2 and 1=0) and (t2<>0) then dec(ans) 142 else if (t1 and 1=0) and ((t2 and 1=1) or (t2=0)) then inc(ans); 143 end; 144 end; 145 end; 146 procedure main; 147 begin 148 ans:=0; 149 for i:=1 to m do 150 begin 151 readln(ll,rr); 152 ll:=(ll+ans) mod n+1;rr:=(rr+ans) mod n+1; 153 if ll>rr then swap(ll,rr); 154 query(ll,rr); 155 writeln(ans); 156 end; 157 end; 158 159 begin 160 assign(input,'input.txt');assign(output,'output.txt'); 161 reset(input);rewrite(output); 162 init; 163 prepare; 164 main; 165 close(input);close(output); 166 end.