• BZOJ 2120/BZOJ 2453


    分块傻逼题。

    memset很慢的。。。而且其实也没有用。。。。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #define maxn 10050
    #define maxm 1000500
    using namespace std;
    int n,m,col[maxn],pre[maxn],last[maxm],b[maxm],pos[maxn],len,num;
    int x,y;
    char s[5];
    void reset(int x)
    {
        int l=(x-1)*len+1,r=min(x*len,n);
        for (int i=l;i<=r;i++)
            b[i]=pre[i];
        sort(b+l,b+r+1);
    }
    void build()
    {
        if (n%len==0) num=n/len;
        else num=n/len+1;
        for (int i=1;i<=num;i++)
            reset(i);
    }
    void change()
    {
        scanf("%d%d",&x,&y);
        for(int i=1;i<=n;i++) last[col[i]]=0;
        col[x]=y;
        for (int i=1;i<=n;i++)
        {
            int regis=pre[i];
            pre[i]=last[col[i]];last[col[i]]=i;
            if (regis!=pre[i]) reset(pos[i]);
        }
    }
    int find(int pos,int x)
    {
        int l=(pos-1)*len+1,r=min(pos*len,n);
        int re=l;
        while (l<=r)
        {
            int mid=(l+r)>>1;
            if (b[mid]<x) l=mid+1;
            else r=mid-1;
        }
        return l-re;
    }
    void ask()
    {
        scanf("%d%d",&x,&y);
        int ans=0;
        if (pos[x]==pos[y])
        {
            for (int i=x;i<=y;i++)
                if (pre[i]<x) ans++;
        }
        else
        {
            for (int i=x;i<=pos[x]*len;i++)
                if (pre[i]<x) ans++;
            for (int i=(pos[y]-1)*len+1;i<=y;i++)
                if (pre[i]<x) ans++;
            for (int i=pos[x]+1;i<=pos[y]-1;i++)
                ans+=find(i,x);
        }
        printf("%d
    ",ans);
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        len=int(sqrt(n)+log(2*n)/log(2));
        for (int i=1;i<=n;i++)
        {
            scanf("%d",&col[i]);
            pre[i]=last[col[i]];
            last[col[i]]=i;
            pos[i]=(i-1)/len+1;
        }
        build();
        for (int i=1;i<=m;i++)
        {
            scanf("%s",s);
            if (s[0]=='Q') ask();
            else change();
        }
        return 0;
    }
  • 相关阅读:
    JavaScript 以POST方式打开新页面
    C# 实现守护进程
    SQL Server 之 使用RowCount遍历表数据
    SQL Server 之 存储过程调用C#编写的dll文件
    C# 多线程学习整理
    java 学习的有用链接
    git 操作命令
    关于各种Map的那些事
    JAVA 反射机制详解
    深入理解java:注解(Anotation)自定义注解
  • 原文地址:https://www.cnblogs.com/ziliuziliu/p/5682597.html
Copyright © 2020-2023  润新知