zoukankan      html  css  js  c++  java
  • 【分块】bzoj2821 作诗(Poetize)

    分块,预处理出:

    ①第i块到第j块之间的偶数值的种类数。

    ②在前i块中,每个值出现的次数。(前缀和)(差分)

    每次询问时,对于不在整块中的元素,进行暴力转移。

    注意:减少memset的使用,千万不要写100000个memset,否则会TLE,宁愿每次询问之后O(sqrt(n))地一个个减掉那个记录每个值出现次数的临时数组。

    Code:

      1 #include<cstdio>
      2 #include<algorithm>
      3 #include<cstring>
      4 #include<cmath>
      5 using namespace std;
      6 int n,kind,m,a[100001],sz,sum,num[100001],l[320],r[320],w[320][320];
      7 int Time[100001],ans,x,y;
      8 int ev[100001][320];
      9 void makeev()
     10 {
     11     for(int i=1;i<=n;i++)
     12       for(int j=num[i];j<=sum;j++)
     13         ev[a[i]][j]++;
     14 }
     15 inline int getsum(const int &v,const int &L,const int &R){return ev[v][R]-ev[v][L-1];}
     16 void makeblock()
     17 {
     18     for(sum=1;sum*sz<n;sum++)
     19       {
     20         l[sum]=(sum-1)*sz+1;
     21         r[sum]=sum*sz;
     22           for(int i=l[sum];i<=r[sum];i++)
     23           num[i]=sum;
     24       }
     25     l[sum]=sz*(sum-1)+1;
     26     r[sum]=n;
     27     for(int i=l[sum];i<=r[sum];i++)
     28       num[i]=sum;
     29 }
     30 void init()
     31 {
     32     for(int i=1;i<=sum;i++)
     33       {
     34           memset(Time,0,sizeof(Time));
     35           for(int j=i;j<=sum;j++)
     36           {
     37             w[i][j]=w[i][j-1];
     38             for(int k=l[j];k<=r[j];k++)
     39               {
     40                 Time[a[k]]++;
     41                 if(!(Time[a[k]]&1))w[i][j]++;
     42                 else if(Time[a[k]]!=1)w[i][j]--;
     43               }
     44           }
     45       }
     46 }
     47 int res,CH[20],Num;char c;
     48 inline int G()
     49 {
     50     res=0;c='*';
     51     while(c<'0'||c>'9')c=getchar();
     52     while(c>='0'&&c<='9'){res=res*10+(c-'0');c=getchar();}
     53     return res;
     54 }
     55 inline void P(int x)
     56 {
     57     if(!x){putchar('0');putchar('
    ');return;}Num=0;  
     58     while(x>0){CH[++Num]=x%10;x/=10;}
     59     while(Num)putchar(CH[Num--]+48);
     60     putchar('
    ');
     61 }
     62 int main()
     63 {
     64     n=G();kind=G();m=G();
     65     sz=sqrt(n);
     66     for(int i=1;i<=n;i++)a[i]=G();
     67     makeblock();init();makeev();
     68     memset(Time,0,sizeof(Time));
     69     for(int i=1;i<=m;i++)
     70       {
     71           x=G();y=G();x=(x+ans)%n+1;y=(y+ans)%n+1;if(x>y)swap(x,y);
     72         ans=w[num[x]+1][num[y]-1];
     73         if(num[x]+1>=num[y])
     74           {
     75               for(int j=x;j<=y;j++)
     76                 {
     77                     Time[a[j]]++;
     78                     if(!(Time[a[j]]&1))ans++;
     79                     else if(Time[a[j]]!=1)ans--;
     80                 }
     81               for(int j=x;j<=y;j++)Time[a[j]]--;
     82           }
     83         else
     84           {
     85               for(int j=x;j<=r[num[x]];j++)
     86               {
     87                   Time[a[j]]++;
     88                   if(!((Time[a[j]]+getsum(a[j],num[x]+1,num[y]-1))&1))ans++;
     89                   else if(Time[a[j]]+getsum(a[j],num[x]+1,num[y]-1)!=1)ans--;
     90               }
     91             for(int j=l[num[y]];j<=y;j++)
     92               {
     93                   Time[a[j]]++;
     94                   if(!((Time[a[j]]+getsum(a[j],num[x]+1,num[y]-1))&1))ans++;
     95                   else if(Time[a[j]]+getsum(a[j],num[x]+1,num[y]-1)!=1)ans--;
     96               }
     97               for(int j=x;j<=r[num[x]];j++)Time[a[j]]--;
     98               for(int j=l[num[y]];j<=y;j++)Time[a[j]]--;
     99           }
    100         P(ans);
    101       }
    102     return 0;
    103 }
    ——The Solution By AutSky_JadeK From UESTC 转载请注明出处:http://www.cnblogs.com/autsky-jadek/
  • 相关阅读:
    冒泡排序-用函数写
    c#语言基础
    c#小知识点
    令人头疼的冒泡排序
    字符串 与函数
    数组 冒泡排序 打印菱形 随机生成不同的数
    if语句练习
    运算符练习
    类型转换
    C#初学
  • 原文地址:https://www.cnblogs.com/autsky-jadek/p/3963324.html
Copyright © 2011-2022 走看看