zoukankan      html  css  js  c++  java
  • P4135 作诗

    题目

      • 很容易想到分块。

      • 类似于区间众数的操作。

      • 首先预处理出两个数组:

        1. f 二维数组表示两个块为左右边界的序列的答案。

        2. s 二维数组处理出从第一个块到某一个块之间每

            个数出现的次数。

      • 对于询问其实和预处理 f 数组的做法差不多。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 int l,r;
     4 int n,m,c,block,sm;
     5 int val[100050];
     6 int f[350][350];
     7 int col[100050];
     8 int L[350],R[350];
     9 int s[350][100050];
    10 int t[100050],ans;
    11 int T[100050],TOP;
    12 void calc()
    13 {
    14     ans=f[col[l]+1][col[r]-1];    TOP=0;
    15     if(col[l]!=col[r])
    16     {
    17         for(int i=l;i<=R[col[l]];++i)
    18             T[++TOP]=val[i];
    19         for(int i=r;i>=L[col[r]];--i)
    20             T[++TOP]=val[i];
    21         for(int i=1;i<=TOP;++i)
    22             t[T[i]]=s[col[r]-1][T[i]]-s[col[l]][T[i]];
    23     }
    24     else
    25     {
    26         for(int i=l;i<=r;++i)
    27             T[++TOP]=val[i];
    28         for(int i=1;i<=TOP;++i)
    29             t[T[i]]=0;
    30     }
    31 }
    32 int main()
    33 {
    34     scanf("%d%d%d",&n,&c,&m);
    35     block=sqrt(n);sm=n/block+1;
    36     for(int i=1;i<=sm;++i)
    37         L[i]=n,R[i]=1;
    38     for(int i=1;i<=n;++i)
    39     {
    40         col[i]=i/block+1;
    41         scanf("%d",&val[i]);
    42         ++s[col[i]][val[i]];
    43         L[col[i]]=min(L[col[i]],i);
    44         R[col[i]]=max(R[col[i]],i);
    45     }
    46     for(int i=1;i<=sm;++i)
    47         for(int j=1;j<=c;++j)
    48             s[i][j]+=s[i-1][j];
    49     for(int i=1;i<=sm;++i)
    50     {
    51         for(int j=L[i];j<=n;++j)
    52         {
    53             ++t[val[j]];
    54             if(t[val[j]]==1)
    55                 ;
    56             else if(t[val[j]]&1)
    57                 --ans;
    58             else    
    59                 ++ans;
    60             if(j==R[col[j]])
    61                 f[i][col[j]]=ans;
    62         }
    63         memset(t,0,sizeof(t));
    64         ans=0;
    65     }
    66     while(m--)
    67     {
    68         scanf("%d%d",&l,&r);
    69         l=(l+ans)%n+1;
    70         r=(r+ans)%n+1;
    71         if(l>r)
    72             swap(l,r);
    73         calc();
    74         for(int i=1;i<=TOP;++i)
    75         {
    76             ++t[T[i]];
    77             if(t[T[i]]==1)
    78                 ;
    79             else if(t[T[i]]&1)
    80                 --ans;
    81             else    
    82                 ++ans;
    83         }
    84         printf("%d
    ",ans);
    85     }
    86     return 0;
    87 }
    View Code
  • 相关阅读:
    HDU 2655 主席树
    Codeforces Round #169 (Div. 2) A水 B C区间更新 D 思路
    Codeforces Round #402 (Div. 2) A B C sort D二分 (水)
    Docker 网络 Flannel
    Docker 搭建 etcd 集群及管理
    Iptables 端口转发
    CentOS7 citus9.5 集群安装及管理
    Ubuntu 忘记密码
    Zookeeper 启动错误
    数据结构 B树 B+树 B*树 LSM-树
  • 原文地址:https://www.cnblogs.com/wyher/p/10428092.html
Copyright © 2011-2022 走看看