• [bzoj] 2453 维护数列 || 单点修改分块


    原题

    询问区间有种个颜色,单点修改某个位置。
    修改次数<=1000


    维护pre[i]为前一个与当前位置颜色一样的位置。
    询问时以pre为关键字sort,lower_bound找pre<x的就是当前区间的答案
    因为修改次数少,所以每次重新搞就行。

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define N 10010
    #define B 100
    #define bel(x) ((x-1)/B+1)
    #define st(x) ((x-1)*B+1)
    #define ed(x) (x==bel(n)?n:(x*B))
    using namespace std;
    int n,q,a[N],pre[N],spre[N],lst[N*100],x,y;
    char op[3];
     
    int read()
    {
        int ans=0,fu=1;
        char j=getchar();
        for (;j<'0' || j>'9';j=getchar()) if (j=='-') fu=-1;
        for (;j>='0' && j<='9';j=getchar()) ans*=10,ans+=j-'0';
        return ans*fu;
    }
     
    int query(int x,int y)
    {
        int ret=0;
        if (bel(x)==bel(y))
        {
        for (int i=x;i<=y;i++)
            if (pre[i]<x) ret++;
        return ret;
        }
        for (int i=x;i==x || i%B!=1;i++)
        if (pre[i]<x) ret++;
        for (int i=y;i==y || i%B!=0;i--)
        if (pre[i]<x) ret++;
        for (int i=bel(x)+1;i<bel(y);i++)
        ret+=lower_bound(spre+st(i),spre+ed(i)+1,x)-(spre+st(i));
        return ret;
    }
     
    void build()
    {
        memset(lst,0,sizeof(lst));
        for (int i=1;i<=n;i++)
        spre[i]=pre[i]=lst[a[i]],lst[a[i]]=i;
        for (int i=1;i<=bel(n);i++)
        sort(spre+st(i),spre+ed(i)+1);
    }
     
    void change()
    {
        for (int i=1;i<=n;i++) lst[a[i]]=0;
        a[x]=y;
        for (int i=1;i<=n;i++)
        {
        int t=pre[i];
        pre[i]=lst[a[i]];
        if (t!=pre[i])
        {
            for(int j=st(bel(i));j<=ed(bel(i));j++)
            spre[j]=pre[j];
            sort(spre+st(bel(i)),spre+ed(bel(i))+1);
        }
        lst[a[i]]=i;
        }
    }
     
    int main()
    {
        n=read();
        q=read();
        for (int i=1;i<=n;i++) a[i]=read();
        build();
        while (q--)
        {
        scanf("%s",op);
        x=read();y=read();
        if (op[0]=='Q') printf("%d
    ",query(x,y));
        else change();
        }
        return 0;
    }
    
  • 相关阅读:
    android 代码上传到jcenter
    android library打包成aar形式供别的项目引用
    使用AndroidStudio导入github项目
    使用Postman在Chrome下进行rest请求测试
    Android 编码规范
    GsonFormat根据返回值json快速构建Model
    码云git使用四(分支的创建,使用和合并)
    码云git使用三(本地代码合并)
    码云git使用二(从码云git服务器上下载到本地)
    计算最长英语单词链
  • 原文地址:https://www.cnblogs.com/mrha/p/8185515.html
Copyright © 2020-2023  润新知