2821: 作诗(Poetize)

2821: 作诗(Poetize)

Time Limit: 50 Sec  Memory Limit: 128 MB
Submit: 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

Sample Output

2
0
0
0
1

HINT

对于100%的数据,1<=n,c,m<=10^5

Source

By lydrainbowcat

挖个坑,以后来填。。。

本来用这题来练分块的,结果完全被二分坑到了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.    
View Code

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.    
View Code
原文地址:https://www.cnblogs.com/zyfzyf/p/3896951.html