zoukankan      html  css  js  c++  java
  • bzoj2120 数颜色——带修莫队

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2120

    带修改的莫队;

    用结构体存下修改和询问,排好序保证时间后就全局移动修改即可;

    参考了TJ:https://blog.csdn.net/SmallSXJ/article/details/69676746

    vis 标记得好精妙啊!这样修改都不用分别改加入和删除了!

    还要注意区间的扩展和收缩在循环上有微妙不同,一定不要写错;

    所以带修莫队也很简洁嘛!

    代码如下:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    int const maxn=1e4+5;
    int n,m,a[maxn],b[maxn],pos[maxn],res,ans[maxn],base,cnt,tot,num[maxn*100];
    bool vis[maxn];
    struct N{int bh,x,y;}ch[maxn];
    struct T{int pre,l,r,id;}q[maxn];
    bool cmp(T x,T y){return (pos[x.l]==pos[y.l])?x.r<y.r:pos[x.l]<pos[y.l];}
    void change(int p)
    {
        if(vis[p])
        {
            num[a[p]]--;
            if(num[a[p]]==0)res--;
        }
        else
        {
            num[a[p]]++;
            if(num[a[p]]==1)res++;
        }
        vis[p]^=1;
    }
    void update(int p,int x)//a[p]=x
    {
        if(vis[p])
        {
            change(p);
            a[p]=x;
            change(p);
        }
        else a[p]=x;
    }
    void work()
    {
        int nw=0,l=1,r=0;//
        for(int i=1;i<=m;i++)
        {
    //        while(nw<=q[i].pre)update(ch[nw].bh,ch[nw].y),nw++;
    //        while(nw>q[i].pre)update(ch[nw].bh,ch[nw].x),nw--;
    //        while(l<q[i].l)change(l),l++;
    //        while(l>q[i].l)change(l),l--;
    //        while(r<q[i].r)change(r),r++;
    //        while(r>q[i].r)change(r),r--;
    //        ans[q[i].id]=res;
            for(int j=nw+1;j<=q[i].pre;j++)
                update(ch[j].bh,ch[j].y);
            for(int j=nw;j>q[i].pre;j--)
                update(ch[j].bh,ch[j].x);
            for(int j=r+1;j<=q[i].r;j++) change(j);//注意扩展和收缩的不同! 
            for(int j=r;j>q[i].r;j--) change(j);
            for(int j=l-1;j>=q[i].l;j--) change(j);
            for(int j=l;j<q[i].l;j++) change(j);
            ans[q[i].id]=res;
            l=q[i].l,r=q[i].r,nw=q[i].pre;
        }
    }
    int main()
    {
        scanf("%d%d",&n,&m); base=sqrt(n);
        for(int i=1;i<=n;i++)
        {
            pos[i]=(i-1)/base+1;
            scanf("%d",&a[i]); b[i]=a[i];
        }
        char cc[3];
        for(int i=1,x,y;i<=m;i++)
        {
            cin>>cc;
            scanf("%d%d",&x,&y);
            if(cc[0]=='R')
            {
                ch[++tot].bh=x; ch[tot].x=b[x]; ch[tot].y=y;
                b[x]=y;
            }
            else q[++cnt].pre=tot,q[cnt].l=x,q[cnt].r=y,q[cnt].id=cnt;
        }
        sort(q+1,q+m+1,cmp);
        work();
        for(int i=1;i<=cnt;i++)printf("%d
    ",ans[i]);
        return 0;
    }
  • 相关阅读:
    75. Sort Colors
    101. Symmetric Tree
    121. Best Time to Buy and Sell Stock
    136. Single Number
    104. Maximum Depth of Binary Tree
    70. Climbing Stairs
    64. Minimum Path Sum
    62. Unique Paths
    css知识点3
    css知识点2
  • 原文地址:https://www.cnblogs.com/Zinn/p/9332556.html
Copyright © 2011-2022 走看看