• 【分块】bzoj2724 [Violet 6]蒲公英


    分块,离散化,预处理出:

    ①前i块中x出现的次数(差分);

    ②第i块到第j块中的众数是谁,出现了多少次。

    询问的时候,对于整块的部分直接获得答案;对于零散的部分,暴力统计每个数出现的次数,加上差分的结果,尝试更新ans。

      1 #include<cstdio>
      2 #include<cmath>
      3 #include<algorithm>
      4 #include<cstring>
      5 using namespace std;
      6 int n,m,sum,sz,num[40001],l[220],r[220],plv[40001][220],mode[220][220],mplv[220][220];
      7 int a[40001],en,Time[40001],x,y,ma[40001],ans;
      8 struct Point{int v,p;}b[40001];
      9 bool operator < (const Point &a,const Point &b){return a.v<b.v;}
     10 int Res,Num;char C,CH[12];
     11 inline int G()
     12 {
     13     Res=0;C='*';
     14     while(C<'0'||C>'9')C=getchar();
     15     while(C>='0'&&C<='9'){Res=Res*10+(C-'0');C=getchar();}
     16     return Res;
     17 }
     18 inline void P(int x)
     19 {
     20     Num=0;if(!x){putchar('0');puts("");return;}
     21     while(x>0)CH[++Num]=x%10,x/=10;
     22     while(Num)putchar(CH[Num--]+48);
     23     puts("");
     24 }
     25 void makeblock()
     26 {
     27     sz=(int)sqrt((double)n); if(!sz) sz=1;
     28     for(sum=1;sum*sz<n;sum++)
     29       {
     30         l[sum]=r[sum-1]+1;
     31         r[sum]=sum*sz;
     32         for(int i=l[sum];i<=r[sum];i++) num[i]=sum;
     33       }
     34     l[sum]=r[sum-1]+1;
     35     r[sum]=n;
     36     for(int i=l[sum];i<=r[sum];i++) num[i]=sum;
     37 }
     38 void LiSan()
     39 {
     40     sort(b+1,b+n+1);
     41     for(int i=1;i<=n;i++)
     42       {
     43         if(b[i].v!=b[i-1].v) en++;
     44         ma[a[b[i].p]=en]=b[i].v;
     45       }
     46 }
     47 void makeplv()
     48 {
     49     for(int i=1;i<=n;i++)
     50       for(int j=num[i];j<=sum;j++)
     51         plv[a[i]][j]++;
     52 }
     53 void makemode()
     54 {
     55     for(int i=1;i<=sum;i++)
     56       {
     57         memset(Time,0,sizeof(Time));
     58         int modenow,modeplv=0;
     59         for(int j=i;j<=sum;j++)
     60           {
     61             for(int k=l[j];k<=r[j];k++)
     62               {
     63                 Time[a[k]]++;
     64                 if(Time[a[k]]>modeplv||(Time[a[k]]==modeplv&&a[k]<modenow))
     65                   {
     66                     modenow=a[k];
     67                     modeplv=Time[a[k]];
     68                   }
     69               }
     70             mode[i][j]=modenow;
     71             mplv[i][j]=modeplv;
     72           }
     73       } memset(Time,0,sizeof(Time));
     74 }
     75 int Getplv(const int &v,const int &L,const int &R){return plv[v][R]-plv[v][L-1];}
     76 int main()
     77 {
     78     n=G(); m=G();
     79     for(int i=1;i<=n;i++) {b[i].v=G(); b[i].p=i;}
     80     makeblock(); LiSan(); makeplv(); makemode();
     81     for(int i=1;i<=m;i++)
     82       {
     83         x=G(); y=G(); x=(x+ans-1)%n+1; y=(y+ans-1)%n+1;
     84         if(x>y) swap(x,y);
     85         int modenow,modeplv=0;
     86         if(num[x]+1>=num[y])
     87           {
     88             for(int j=x;j<=y;j++)
     89               {
     90                 Time[a[j]]++;
     91                 if(Time[a[j]]>modeplv||(Time[a[j]]==modeplv&&a[j]<modenow))
     92                   {
     93                     modenow=a[j];
     94                     modeplv=Time[a[j]];
     95                   }
     96               }
     97             for(int j=x;j<=y;j++) Time[a[j]]--;
     98           }
     99         else
    100           {
    101             modenow=mode[num[x]+1][num[y]-1];
    102             modeplv=mplv[num[x]+1][num[y]-1];
    103             for(int j=x;j<=r[num[x]];j++)
    104               {
    105                 Time[a[j]]++; int t=Time[a[j]]+Getplv(a[j],num[x]+1,num[y]-1);
    106                 if(t>modeplv||(t==modeplv&&a[j]<modenow))
    107                   {
    108                     modenow=a[j];
    109                     modeplv=t;
    110                   }
    111               }
    112             for(int j=l[num[y]];j<=y;j++)
    113               {
    114                 Time[a[j]]++; int t=Time[a[j]]+Getplv(a[j],num[x]+1,num[y]-1);
    115                 if(t>modeplv||(t==modeplv&&a[j]<modenow))
    116                   {
    117                     modenow=a[j];
    118                     modeplv=t;
    119                   }
    120               }
    121             for(int j=x;j<=r[num[x]];j++) Time[a[j]]--;
    122             for(int j=l[num[y]];j<=y;j++) Time[a[j]]--;
    123           }
    124         P(ans=ma[modenow]);
    125       }
    126     return 0;
    127 }
  • 相关阅读:
    spring学习(十七)--annotion注解
    spring学习(十六)--spring方式实现工程初始化配置
    spring学习(十五)--自己实现BeanFactory
    JDBC使用SPI机制解析
    SPI机制
    spring学习(十三)--自己实现SpringServletContainerInitializer
    cetnos基本操作
    CentOS基本命令
    面向对象的双下方法
    Flask数据连接池 DBUtils
  • 原文地址:https://www.cnblogs.com/autsky-jadek/p/4077265.html
Copyright © 2020-2023  润新知