• bzoj 2120: 数颜色


     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cmath>
     4 #include<algorithm>
     5 #define M 1000009
     6 using namespace std;
     7 int block,n,m,a[M],b[M],pre[M],pos[M],last[M],l[M],r[M],m1;
     8 int ask(int a1,int a2)
     9 {
    10     int ans=0;
    11     if(pos[a1]==pos[a2])
    12       {
    13         for(int i=a1;i<=a2;i++)
    14           if(b[i]<a1)
    15             ans++;
    16       }
    17     else
    18       {
    19         for(int i=a1;i<=r[pos[a1]];i++)
    20           if(b[i]<a1)
    21             ans++;
    22         for(int i=l[pos[a2]];i<=a2;i++)
    23           if(b[i]<a1)
    24             ans++;
    25         for(int i=pos[a1]+1;i<pos[a2];i++)
    26           ans+=lower_bound(pre+l[i],pre+r[i]+1,a1)-pre-l[i];
    27       }
    28     return ans;  
    29 }
    30 void jian(int i)
    31 {
    32     l[i]=(i-1)*block+1;
    33     r[i]=min(n,i*block);
    34     for(int j=l[i];j<=r[i];j++)
    35         pre[j]=b[j];
    36     sort(pre+l[i],pre+r[i]+1);
    37 }
    38 void gai(int x,int y)
    39 {
    40     for(int i=1;i<=n;i++)
    41       last[a[i]]=0;
    42     a[x]=y;
    43     for(int i=1;i<=n;i++)
    44       {
    45         int t=b[i];
    46         b[i]=last[a[i]];
    47         if(t!=last[a[i]])
    48           jian(pos[i]);
    49         last[a[i]]=i;
    50       }
    51 }
    52 int main()
    53 {
    54     scanf("%d%d",&n,&m1);
    55     for(int i=1;i<=n;i++)
    56       scanf("%d",&a[i]);
    57     block=(int)sqrt(n+log(2*n)/log(2));
    58     m=n/block;
    59     if(n%block)
    60       m++;
    61     for(int i=1;i<=n;i++)
    62       {
    63         b[i]=last[a[i]];
    64         last[a[i]]=i;
    65         pos[i]=(i-1)/block+1;
    66       }
    67     for(int i=1;i<=m;i++)
    68       jian(i);
    69     for(int i=1;i<=m1;i++)
    70       {
    71         char ch[5];
    72         int a1,a2;
    73         scanf("%s%d%d",ch,&a1,&a2);
    74         if(ch[0]=='Q')
    75           printf("%d
    ",ask(a1,a2));
    76         else
    77           gai(a1,a2);
    78       }
    79     return 0;
    80 }

    暴力分块,每个点存下一个与他相同颜色的在哪,每个块内排序,找的时候首尾暴力判断每个点下一个颜色在不在区间外,不在就答案加加,中间二分。修改时重建每个点存的下一个点,

    如果改了,就重建这个块。

  • 相关阅读:
    关于react-native遇到Can't find variable: TouchableHighlight
    安卓---app自动更新
    安卓---android:versionCode和android:versionName 用途
    安卓---读取照片---拍照
    运营商如何识别电信诈骗用户
    再要你命3K的任务总结
    连接kettle(6.1)与vm上的apache hadoop(2.6.1)
    如何从数据上知道某个用户即将去香港
    什么是撼动社会的产品?
    与Y哥的谈话。
  • 原文地址:https://www.cnblogs.com/xydddd/p/5294024.html
Copyright © 2020-2023  润新知