博客园 首页 私信博主 显示目录 隐藏目录 管理 动画

「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 }
「BZOJ2821」作诗
 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 }
「BZOJ2724」蒲公英

 

posted @ 2019-08-07 07:43  gllonkxc  阅读(114)  评论(0编辑  收藏  举报