zoukankan      html  css  js  c++  java
  • 洛谷 P4168 [Violet]蒲公英(分块)

    传送门


    解题思路

    一言一概之,动态求区间众数。

    瞄一眼数据范围,大约n根号n——分块大法好!

    先把读入的数据离散化,然后进行分块处理。

    对于每一个询问,把它分成整块和零散快处理:

    • 整块:预处理i到j块的众数,直接O(1)询问。
    • 零散快:预处理从1到n每个数出现的位置,枚举零散快的数字,二分查找询问的区间内的个数,与整块的众数作比较。

    预处理众数:枚举起始块,向右暴力枚举,O(n*块数)

    预处理数字位置:扫一遍,加入vector中即可

    假设块数为T,则时间复杂度为O(n*T+m*n/T*log(n)),所以当n*T=m*n/T*log(n)时,和最小,所以T=sqrt(m*logn)。

    按照sqrt(n)也能水过去

    AC代码

     1 #include<iostream>
     2 #include<algorithm>
     3 #include<cmath>
     4 #include<cstdio>
     5 #include<cstring>
     6 #include<cstdlib>
     7 #include<queue>
     8 #include<set>
     9 #include<map>
    10 #include<vector>
    11 #include<iomanip>
    12 #include<ctime>
    13 #include<stack>
    14 using namespace std;
    15 const int maxn=40005;
    16 vector<int> v[maxn];
    17 int n,m,sq,a[maxn],aa[maxn],q[maxn],cnt,now=1,l[maxn],r[maxn],id[maxn],c[maxn],mode[1005][1005]; 
    18 int ll,rr,anss;
    19 int main()
    20 {
    21     cin>>n>>m;
    22     sq=sqrt(m);
    23     if(sq*sq<m) sq++;
    24     for(int i=1;i<=n;i++) {
    25         scanf("%d",&aa[i]);
    26         q[i]=aa[i];
    27     }
    28     sort(q+1,q+n+1);
    29     int len=unique(q+1,q+n+1)-q-1;
    30     for(int i=1;i<=n;i++) a[i]=lower_bound(q+1,q+len+1,aa[i])-q;
    31     l[now]=1;
    32     for(int i=1;i<=n;i++){
    33         if(cnt==sq){
    34             r[now++]=i-1;
    35             l[now]=i;
    36             cnt=0;
    37         }
    38         cnt++;
    39         id[i]=now;
    40     }
    41     r[now]=n;
    42     for(int i=1;i<=sq;i++){
    43         memset(c,0,sizeof(c));
    44         int maxx=0;
    45         for(int j=i;j<=sq;j++){
    46             for(int k=l[j];k<=r[j];k++){
    47                 c[a[k]]++;
    48                 if((c[a[k]]>c[maxx])||(c[a[k]]==c[maxx]&&a[k]<maxx)) maxx=a[k];
    49             }
    50             mode[i][j]=maxx;
    51         }
    52     }
    53     for(int i=1;i<=n;i++) v[a[i]].push_back(i);
    54     int ans=0;
    55     for(int i=1;i<=m;i++){
    56         anss=0; 
    57         scanf("%d%d",&ll,&rr);
    58         ll=(ll+q[ans]-1)%n+1;
    59         rr=(rr+q[ans]-1)%n+1;
    60         if(ll>rr) swap(ll,rr);
    61         if(id[ll]==id[rr]){
    62             for(int j=ll;j<=rr;j++){
    63                 int noww=upper_bound(v[a[j]].begin(),v[a[j]].end(),rr)-lower_bound(v[a[j]].begin(),v[a[j]].end(),ll);
    64                 if((noww>anss)||(noww==anss&&a[j]<ans)) ans=a[j],anss=noww;
    65             }
    66         }else{
    67             int noww=0;
    68             if(id[ll]!=id[rr]-1){
    69                 ans=mode[id[ll]+1][id[rr]-1];
    70                 anss=upper_bound(v[ans].begin(),v[ans].end(),rr)-lower_bound(v[ans].begin(),v[ans].end(),ll);
    71             }
    72             for(int j=ll;j<=r[id[ll]];j++){
    73                 noww=upper_bound(v[a[j]].begin(),v[a[j]].end(),rr)-lower_bound(v[a[j]].begin(),v[a[j]].end(),ll);
    74                 if((noww>anss)||(noww==anss&&a[j]<ans)) ans=a[j],anss=noww;
    75             }
    76             for(int j=l[id[rr]];j<=rr;j++){
    77                 noww=upper_bound(v[a[j]].begin(),v[a[j]].end(),rr)-lower_bound(v[a[j]].begin(),v[a[j]].end(),ll);
    78                 if((noww>anss)||(noww==anss&&a[j]<ans)) ans=a[j],anss=noww;
    79             }
    80         }
    81         printf("%d
    ",q[ans]);
    82     }
    83     return 0;
    84 }
  • 相关阅读:
    PostgreSQL Replication之第四章 设置异步复制(4)
    PostgreSQL Replication之第四章 设置异步复制(3)
    PostgreSQL Replication之第四章 设置异步复制(2)
    PostgreSQL Replication之第四章 设置异步复制(1)
    PostgreSQL Replication之第三章 理解即时恢复(4)
    Hdu3065 病毒侵袭持续中
    poj3974 Palindrome
    poj1204 Word Puzzles
    Hdu2222 Keywords Search
    Codeforce 633.C Spy Syndrome 2
  • 原文地址:https://www.cnblogs.com/yinyuqin/p/14402868.html
Copyright © 2011-2022 走看看