• 解题:洛谷1903 数颜色/维护队列


    题面

    大力分块艹过去了

    直接分块+bitset,离散化后记录每块内每种颜色出现的次数,这样一次修改是$O(1)$的(不算离散化的话)。然而查询时因为要合并块,所以复杂度是整块长度之和这个级别的的(虽然有个bitset的$frac{1}{32}$),直接把块大小$siz$设成$sqrt(n)$做大概会比较慢。

    为了提高效率,这里可以适当加大块的大小,这样块合并会变少而零散区间的统计会变多,在这个题效率会更高一点(我一开始弄了一个$n^{frac{3}{5}}$的块大小(块最大的时候大概是660)卡过去了,最慢的点跑了600+ms,后来又试了试然后还加了个“输出优化(不知道有没有用啊=。=)”,把块大小搞成$n^{frac{3}{4}}$跑的更快了些(块最大的时候大概是3400),就是上面说的300ms+)

     1 // luogu-judger-enable-o2
     2 #include<cmath>
     3 #include<cstdio>
     4 #include<cctype>
     5 #include<bitset>
     6 #include<cstring>
     7 #include<algorithm>
     8 using namespace std;
     9 const int N=50005,M=100005,Sq=20;
    10 struct a
    11 {
    12     int typ;
    13     int ll,rr;
    14 }q[N];
    15 int n,m,t1,t2,t3,t4,sqr,cnt,xnt,len;
    16 int pts[Sq][2],app[Sq][M]; 
    17 int a[N],blo[N],uni[2*N];
    18 bitset<M> sta[Sq],qry; 
    19 char rd[5];
    20 inline int read()
    21 {
    22     int ret=0;
    23     char ch=getchar();
    24     while(!isdigit(ch))
    25         ch=getchar();
    26     while(isdigit(ch))
    27         ret=(ret<<1)+(ret<<3)+(ch^48),ch=getchar();
    28     return ret;
    29 }
    30 inline void write(int x)
    31 {
    32     if(x>9) write(x/10);
    33     putchar(x%10+48);
    34 }
    35 int main()
    36 {
    37     register int i,j;
    38     n=read(),m=read(),xnt=n;
    39     sqr=pow(n,0.75),pts[cnt=1][0]=1;
    40     for(i=1;i<=n;i++)
    41     {
    42         a[i]=read(),uni[i]=a[i];
    43         blo[i]=(i-1)/sqr+1;
    44         if(i%sqr==0)
    45         {
    46             pts[cnt++][1]=i;
    47             pts[cnt][0]=i+1; 
    48         }
    49     }
    50     pts[cnt][1]=n; 
    51     for(i=1;i<=m;i++)
    52     {
    53         scanf("%s",rd),t1=read(),t2=read();
    54         q[i].ll=t1,q[i].rr=t2,q[i].typ=(rd[0]=='R');
    55         if(q[i].typ) uni[++xnt]=t2;
    56     }
    57     sort(uni+1,uni+1+xnt),len=unique(uni+1,uni+1+xnt)-uni-1;
    58     for(i=1;i<=n;i++)
    59     {
    60         a[i]=lower_bound(uni+1,uni+1+len,a[i])-uni;
    61         if(++app[blo[i]][a[i]]==1) sta[blo[i]][a[i]]=true;
    62     }
    63     for(i=1;i<=m;i++)
    64     {
    65         t1=q[i].ll,t2=q[i].rr;
    66         if(q[i].typ)
    67         {
    68             int bel=blo[t1],newc=lower_bound(uni+1,uni+1+len,t2)-uni;
    69             if(!(--app[bel][a[t1]])) sta[bel][a[t1]]=false;
    70             if(++app[bel][newc]==1) sta[bel][newc]=true; a[t1]=newc;
    71         }
    72         else 
    73         {
    74             qry.reset(),t3=blo[t1],t4=blo[t2];
    75             if(t3!=t4)
    76             {
    77                 for(j=t1;j<=pts[t3][1];j++) qry[a[j]]=true;
    78                 for(j=pts[t4][0];j<=t2;j++) qry[a[j]]=true;
    79                 for(j=t3+1;j<=t4-1;j++) qry|=sta[j];
    80             }
    81             else for(j=t1;j<=t2;j++) qry[a[j]]=true;
    82             write((int)qry.count()),puts("");
    83         }
    84     }
    85     return 0;
    86 } 
    View Code
  • 相关阅读:
    Wix 教程
    SQL插入數據變成?解決辦法
    DevExpress GridControl使用方法总结【轉】
    Javascript如何判断对象是否相等【轉】
    android StringBuffer类的使用
    Linux命令
    PHP解决中文乱码
    PHP防盗链技术
    0113进度条+ListView+ArrayList+Adapter用法
    Windows中32位(x86)和64位(x64)解释
  • 原文地址:https://www.cnblogs.com/ydnhaha/p/9960350.html
Copyright © 2020-2023  润新知