「BZOJ2821」作诗 && 「BZOJ2724」蒲公英
题目大意(蒲公英):多次询问求区间众数,不带修,强制在线
题目大意(作诗):多次询问求区间中出现偶数次的数的个数,不带修,强制在线
做法:发现都是强制在线,所以优秀的莫队算法就没用了:(
然后我们套路性的设$F_{i,j}$为i~j块中的答案,然后对两边剩下的至多$2\sqrt n$个数单独处理。
效率是$O(M\sqrt N log_2 N)$
细节:(作诗)*单独处理的时候需要数$x$看在块$[bl_l+1,bl_r-1]$中是否有出现,如果没有的话会直接判断在大小区间中奇偶性是否相同会多减
1 // luogu-judger-enable-o2 2 #include<bits/stdc++.h> 3 using namespace std; 4 #define ll long long 5 inline ll read() { 6 ll x=0,f=1; char ch=getchar(); 7 for(;ch<'0'||ch>'9';ch=getchar()) 8 if(ch=='-')f=-f; 9 for(;ch>='0'&&ch<='9';ch=getchar()) 10 x=x*10+ch-'0'; 11 return x*f; 12 } 13 inline void chkmin( int &a,int b ) { if(a>b) a=b; } 14 inline void chkmax( int &a,int b ) { if(a<b) a=b; } 15 #define _ read() 16 #define ln endl 17 const int N=2e5+5; 18 int n,c,m,sz,a[N],F[3005][3005],bl[N],vis[N]; 19 vector<int> v[N]; 20 int main() { 21 // freopen("0.in","r",stdin); 22 n=_; c=_; m=_; sz=sqrt((double)n/log((double)n)*log(2)); 23 for( int i=1;i<=n;i++ ) a[i]=_; 24 for( int i=1;i<=n;i++ ) v[a[i]].push_back(i); 25 for( int i=1;i<=n;i++ ) 26 bl[i]=(i-1)/sz+1; 27 for( int i=1;i<=bl[n];i++ ) { 28 for( int j=1;j<=c;j++ ) vis[j]=0; 29 int ans=0; 30 for( int j=(i-1)*sz+1;j<=n;j++ ) { 31 vis[a[j]]++; 32 if((vis[a[j]]&1)==1&&(vis[a[j]]!=1)) --ans; 33 else if((vis[a[j]]&1)==0) ++ans; 34 F[i][bl[j]]=ans; 35 } 36 } 37 int lstans=0; 38 while(m--) { 39 int l=_,r=_,ans=0; 40 l=(l+lstans)%n+1; r=(r+lstans)%n+1; 41 if(l>r) swap(l,r); 42 ans=F[bl[l]+1][bl[r]-1]; 43 for( int i=l;i<=min(bl[l]*sz,r);i++ ) vis[a[i]]=0; 44 for( int i=max(l,(bl[r]-1)*sz+1);i<=r;i++ ) vis[a[i]]=0; 45 for( int i=l;i<=min(bl[l]*sz,r);i++ ) { 46 int x=a[i]; if(vis[x]) continue; vis[x]=1; 47 int L=lower_bound(v[x].begin(),v[x].end(),l)-v[x].begin(); 48 int R=upper_bound(v[x].begin(),v[x].end(),r)-v[x].begin(); --R; 49 int LL=lower_bound(v[x].begin(),v[x].end(),bl[l]*sz+1)-v[x].begin(); 50 int RR=upper_bound(v[x].begin(),v[x].end(),(bl[r]-1)*sz)-v[x].begin(); --RR; 51 if(((R-L+1)&1)!=((RR-LL+1)&1)||(LL>RR)) { 52 if(((R-L+1)&1)&&(R-L+1!=1)&&LL<=RR) --ans; 53 else if((R-L+1)%2==0) ++ans; 54 } 55 } 56 for( int i=max(l,(bl[r]-1)*sz+1);i<=r;i++ ) { 57 int x=a[i]; if(vis[x]) continue; vis[x]=1; 58 int L=lower_bound(v[x].begin(),v[x].end(),l)-v[x].begin(); 59 int R=upper_bound(v[x].begin(),v[x].end(),r)-v[x].begin(); --R; 60 int LL=lower_bound(v[x].begin(),v[x].end(),bl[l]*sz+1)-v[x].begin(); 61 int RR=upper_bound(v[x].begin(),v[x].end(),(bl[r]-1)*sz)-v[x].begin(); --RR; 62 if(((R-L+1)&1)!=((RR-LL+1)&1)||(LL>RR)) { 63 if(((R-L+1)&1)&&(R-L+1!=1)&&LL<=RR) --ans; 64 else if((R-L+1)%2==0) ++ans; 65 } 66 } 67 printf("%d\n",lstans=ans); 68 // cout<<(lstans=ans)<<ln; 69 } 70 }
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define ll long long 4 inline ll read() { 5 ll x=0,f=1; char ch=getchar(); 6 for(;ch<'0'||ch>'9';ch=getchar()) 7 if(ch=='-')f=-f; 8 for(;ch>='0'&&ch<='9';ch=getchar()) 9 x=x*10+ch-'0'; 10 return x*f; 11 } 12 inline void chkmin( int &a,int b ) { if(a>b) a=b; } 13 inline void chkmax( int &a,int b ) { if(a<b) a=b; } 14 #define _ read() 15 #define ln endl 16 const int N=50005; 17 int n,m,sz,b[N],a[N],F[505][505],bl[N],vis[N]; 18 vector < int > v[N]; 19 inline int query( int x,int l,int r ) { 20 int L=lower_bound(v[x].begin(),v[x].end(),l)-v[x].begin(); 21 int R=upper_bound(v[x].begin(),v[x].end(),r)-v[x].begin(); --R; 22 return R-L+1; 23 } 24 int main() { 25 n=_; m=_; sz=sqrt(n); 26 for( int i=1;i<=n;i++ ) b[i]=a[i]=_,bl[i]=(i-1)/sz+1; 27 sort(b+1,b+n+1); int len=unique(b+1,b+n+1)-b-1; 28 for( int i=1;i<=n;i++ ) a[i]=lower_bound(b+1,b+len+1,a[i])-b,v[a[i]].push_back(i); 29 for( int i=1;i<=bl[n];i++ ){ 30 int ans=0; 31 for( int j=1;j<=len;j++ ) vis[j]=0; 32 for( int j=(i-1)*sz+1;j<=n;j++ ) { 33 vis[a[j]]++; 34 if(vis[a[j]]>vis[ans]) ans=a[j]; 35 else if(vis[a[j]]==vis[ans]) ans=min(ans,a[j]); 36 F[i][bl[j]]=ans; 37 } 38 } 39 int lstans=0; 40 while(m--) { 41 int l=_,r=_,ans=0,ans2=0; 42 l=(l+lstans-1)%n+1; r=(r+lstans-1)%n+1; 43 if(l>r) swap(l,r); 44 ans=F[bl[l]+1][bl[r]-1]; ans2=query(ans,l,r); 45 for( int i=l;i<=min(bl[l]*sz,r);i++ ) { 46 int x=a[i],tmp1=query(x,l,r); 47 if(tmp1>ans2) ans=x,ans2=tmp1; 48 else if(tmp1==ans2) ans=min(ans,x); 49 } 50 for( int i=max(l,(bl[r]-1)*sz+1);i<=r;i++ ) { 51 int x=a[i],tmp1=query(x,l,r); 52 if(tmp1>ans2) ans=x,ans2=tmp1; 53 else if(tmp1==ans2) ans=min(ans,x); 54 } 55 printf("%d\n",lstans=b[ans]); 56 } 57 }