zoukankan      html  css  js  c++  java
  • P1903 [国家集训队]数颜色 / 维护队列

    传送门

    带修莫队,在原来的基础上加一个时间指针 $t$

    每次移动时除了 $l,r$ 移动 $t$ 也跟着移动,并更新状态

    为了维护时间变化

    所以维护一个 $pos[i]$ 表示第 $i$ 次修改的位置,$co[i]$ 表示第 $i$ 次修改的颜色

    $pre[i]$ 表示第 $i$ 次修改前 $pos[i]$ 的颜色

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    using namespace std;
    typedef long long ll;
    inline int read()
    {
        int x=0,f=1; char ch=getchar();
        while(ch<'0'||ch>'9') { if(ch=='-') f=-1; ch=getchar(); }
        while(ch>='0'&&ch<='9') { x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); }
        return x*f;
    }
    const int N=1e5+7,M=1e6+7;
    int n,m,Div;
    int cnt[M],col[N],ans[N];//col维护当前序列状态
    int pos[N],pre[N],co[N];
    struct dat{
        int l,r,t,bel;
        inline bool operator < (const dat &tmp) const {
            if(l/Div!=tmp.l/Div) return l/Div<tmp.l/Div;
            return r/Div!=tmp.r/Div ? r/Div<tmp.r/Div : t/Div<tmp.t/Div;
        }
    }q[N];
    int main()
    {
        n=read(),m=read();
        for(int i=1;i<=n;i++) col[i]=read();
        int ta=0,tb=0,a,b; char s[7];
        for(int i=1;i<=m;i++)
        {
            scanf("%s",s); a=read(),b=read();
            if(s[0]=='Q')
                q[++ta]=(dat){a,b,tb,ta};
            else
            {
                tb++; pos[tb]=a; co[tb]=b;
                pre[tb]=col[a]; col[a]=b;
            }
        }
        for(int i=tb;i;i--) col[pos[i]]=pre[i];//把序列的修改撤销回来
        Div=ceil( exp( (log(n)+log(tb))/3 ) );//奇怪的块大小
        sort(q+1,q+ta+1);
        int l=1,r=0,t=0,tot=0;
        for(int i=1;i<=ta;i++)
        {
            while(q[i].l<l) tot+=!cnt[col[--l]]++;
            while(q[i].l>l) tot-=!--cnt[col[l++]];
            while(q[i].r<r) tot-=!--cnt[col[r--]];
            while(q[i].r>r) tot+=!cnt[col[++r]]++;
            while(q[i].t<t)//移动时间指针
            {
                if(pos[t]>=l&&pos[t]<=r) tot-=!--cnt[col[ pos[t] ]];
                col[pos[t]]=pre[t];
                if(pos[t]>=l&&pos[t]<=r) tot+=!cnt[col[ pos[t] ]]++;
                t--;
            }
            while(q[i].t>t)//移动时间指针
            {
                t++;
                if(pos[t]>=l&&pos[t]<=r) tot-=!--cnt[col[ pos[t] ]];
                col[pos[t]]=co[t];
                if(pos[t]>=l&&pos[t]<=r) tot+=!cnt[col[ pos[t] ]]++;
            }
            ans[q[i].bel]=tot;
        }
        for(int i=1;i<=ta;i++) printf("%d
    ",ans[i]);
        return 0;
    }

     

  • 相关阅读:
    BEC listen and translation exercise 44
    中译英12
    BEC listen and translation exercise 43
    中译英11
    BEC listen and translation exercise 42
    中译英10
    BEC listen and translation exercise 41
    中译英9
    BEC listen and translation exercise 40
    中译英8
  • 原文地址:https://www.cnblogs.com/LLTYYC/p/10630996.html
Copyright © 2011-2022 走看看