P4168 [Violet]蒲公英(分块求区间众数)

题目:传送门

思路:预处理出数字 j 在前 i 个块中对应的前缀和 sum[i][j] ,和 第 i 个块到第 j 个块的众数 res[i][j] ; 对于询问直接按块或块内暴力即可。

代码:

  1 //#include<bits/stdc++.h>
  2 
  3 #include<cstdio>
  4 #include<cmath>
  5 #include<cstring>
  6 #include<vector>
  7 #include<cctype>
  8 #include<queue>
  9 #include<algorithm>
 10 #include<map>
 11 #include<set>
 12 
 13 #pragma GCC optimize(2)
 14 using namespace std;
 15 typedef long long LL;
 16 typedef pair<int,int> pii;
 17 typedef pair<double,double> pdd;
 18 const int N=4e4+5;
 19 const int M=1e4+5;
 20 const int inf=0x3f3f3f3f;
 21 const LL mod=1e9+7;
 22 const double eps=1e-9;
 23 const long double pi=acos(-1.0L);
 24 #define ls (i<<1)
 25 #define rs (i<<1|1)
 26 #define fi first
 27 #define se second
 28 #define pb push_back
 29 #define mk make_pair
 30 #define mem(a,b) memset(a,b,sizeof(a))
 31 LL read()
 32 {
 33     LL x=0,t=1;
 34     char ch;
 35     while(!isdigit(ch=getchar())) if(ch=='-') t=-1;
 36     while(isdigit(ch)){ x=10*x+ch-'0'; ch=getchar(); }
 37     return x*t;
 38 }
 39 int l[N],r[N],sum[205][N],res[205][205],t[N],a[N],len,tmp[N],m,n,block,tot;
 40 inline int getid(int x)
 41 {
 42     return lower_bound(t+1,t+len+1,x)-t;
 43 }
 44 void build()
 45 {
 46     block=sqrt(1.0*n);
 47     tot=n/block;
 48     if(block*tot<n) tot++;
 49     for(int i=1;i<=tot;i++) l[i]=block*(i-1)+1,r[i]=block*i;
 50     r[tot]=min(n,r[tot]);
 51     for(int i=1;i<=n;i++)
 52     {
 53         int id=(i+block-1)/block;
 54         sum[id][a[i]]++;
 55     }
 56     for(int i=1;i<=tot;i++)
 57         for(int j=1;j<=len;j++)
 58             sum[i][j]+=sum[i-1][j];
 59     for(int i=1;i<=tot;i++)
 60         for(int j=i;j<=tot;j++)
 61         {
 62             int &x=res[i][j];
 63             x=res[i][j-1];
 64             int ma=sum[j][x]-sum[i-1][x];
 65             for(int k=l[j];k<=r[j];k++)
 66                 if(ma<sum[j][a[k]]-sum[i-1][a[k]]||ma==sum[j][a[k]]-sum[i-1][a[k]]&&x>a[k])
 67                 {
 68                     ma=sum[j][a[k]]-sum[i-1][a[k]];
 69                     x=a[k];
 70                 }
 71         }
 72    /*for(int i=1;i<=tot;i++)
 73         for(int j=i;j<=tot;j++)
 74             printf("%d%c",res[i][j],j==tot?'\n':' ');*/
 75 
 76 }
 77 int query(int x,int y)
 78 {
 79     int dx=(x+block-1)/block;
 80     int dy=(y+block-1)/block;
 81     int ans,ma;
 82     if(dx==dy)
 83     {
 84         ans=0,ma=0;
 85         for(int i=x;i<=y;i++)
 86             if(++tmp[a[i]]>ma||tmp[a[i]]==ma&&ans>a[i])
 87                 ma=tmp[a[i]],ans=a[i];
 88         for(int i=x;i<=y;i++) tmp[a[i]]=0;
 89     }
 90     else
 91     {
 92         ans=res[dx+1][dy-1];
 93         ma=sum[dy-1][ans]-sum[dx][ans];
 94         for(int i=x;i<=r[dx];i++)
 95             if(++tmp[a[i]]+sum[dy-1][a[i]]-sum[dx][a[i]]>ma||tmp[a[i]]+sum[dy-1][a[i]]-sum[dx][a[i]]==ma&&ans>a[i])
 96                 ma=tmp[a[i]]+sum[dy-1][a[i]]-sum[dx][a[i]],ans=a[i];
 97         for(int i=l[dy];i<=y;i++)
 98             if(++tmp[a[i]]+sum[dy-1][a[i]]-sum[dx][a[i]]>ma||tmp[a[i]]+sum[dy-1][a[i]]-sum[dx][a[i]]==ma&&ans>a[i])
 99                 ma=tmp[a[i]]+sum[dy-1][a[i]]-sum[dx][a[i]],ans=a[i];
100         for(int i=x;i<=r[dx];i++) tmp[a[i]]=0;
101         for(int i=l[dy];i<=y;i++) tmp[a[i]]=0;
102     }
103     return ans;
104 }
105 int main()
106 {
107     //freopen("input.txt","r",stdin);
108     n=read(); m=read();
109     for(int i=1;i<=n;i++) a[i]=read(),t[i]=a[i];
110     sort(t+1,t+n+1);
111     len=unique(t+1,t+n+1)-t-1;
112     for(int i=1;i<=n;i++) a[i]=getid(a[i]);
113     build();
114     int ans=0;
115     for(int i=1;i<=m;i++)
116     {
117         int x=read(),y=read();
118         x=(x+ans-1)%n+1;
119         y=(y+ans-1)%n+1;
120         if(x>y) swap(x,y);
121         ans=t[query(x,y)];
122         //printf("l = %d , r = %d\n",x,y);
123         printf("%d\n",ans);
124     }
125     return 0;
126 }
127 /*
128 7 4
129 4 4 3 1 1 4 100324433
130 1 5
131 3 6
132 1 5
133 1 7
134 */
View Code

猜你喜欢

转载自www.cnblogs.com/DeepJay/p/12940056.html