zoukankan      html  css  js  c++  java
  • bzoj2120: 数颜色

    妈也第三次补莫队。。。

    好吧大概是以后不用补了。

    讲一讲,首先操作就是离线,把询问和修改记录下来,特别要注意的,询问要记录该询问前有多少个修改ti,修改要记录修改前的颜色pre。

    第二步就是分块,然后按l,r,ti块的顺序排序

    然后这个暴力怎么写呢。

    主要的思想就是将当前的延伸到要求的。带修就是三维l,r,T了。

    假设当前求出了一个询问,那么l,r,T,都等于这个询问的值,按顺序要求新询问

    那么按照T,l,r的顺序,暴力恢复到满足三个条件就可以了。

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    
    int n,m,a[11000];
    
    struct query
    {
        int l,r,ti,id;
    }q[11000];int qlen;
    struct change_color
    {
        int ip,now,pre;//pre记录这个修改前的颜色 
    }c[11000];int clen,last[11000];//last是最后的颜色 
    
    int block,st[11000];
    bool cmp(query n1,query n2)
    {
        if((st[n1.l]<st[n2.l]) ||
            (st[n1.l]==st[n2.l]&&st[n1.r]<st[n2.r]) ||
                (st[n1.l]==st[n2.l]&&st[n1.r]==st[n2.r]&&st[n1.ti]<st[n2.ti]))
                    return true;
        return false;
    }
    
    int as[11000];
    int col[1100000],ans;
    void change(int x,int k)
    {
        col[x]+=k;
        if(k==-1&&col[x]==0)ans--;
        if(k==1&&col[x]==1)ans++;
    }
    void solve()
    {
        int l=1,r=0,T=0;
        for(int i=1;i<=qlen;i++)
        {
            while(T<q[i].ti)
            {
                T++;
                if(l<=c[T].ip&&c[T].ip<=r)//释放对答案的影响 
                    change(a[c[T].ip],-1), change(c[T].now,1);
                a[c[T].ip]=c[T].now;//位置的颜色更改
            }//时间加速
            while(T>q[i].ti)
            {
                if(l<=c[T].ip&&c[T].ip<=r)
                    change(a[c[T].ip],-1), change(c[T].pre,1);
                a[c[T].ip]=c[T].pre;
                T--;
            }//时间倒流
            
            //ti
            
            while(l<q[i].l)change(a[l],-1), l++;
            while(l>q[i].l)l--, change(a[l],1);
            while(r<q[i].r)r++, change(a[r],1);
            while(r>q[i].r)change(a[r],-1), r--;
            //l&r
            
            as[q[i].id]=ans;
        }
    }
    
    char ss[20];
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
            scanf("%d",&a[i]), last[i]=a[i];
            
        int x,y;
        for(int i=1;i<=m;i++)
        {
            scanf("%s%d%d",ss+1,&x,&y);
            if(ss[1]=='Q')
            {
                qlen++;
                q[qlen].l=x;q[qlen].r=y;
                q[qlen].ti=clen;q[qlen].id=qlen;
            }//qins
            else if(ss[1]=='R')
            {
                clen++;
                c[clen].ip=x;c[clen].now=y;
                c[clen].pre=last[x];last[x]=y;
            }//cins
        }
        
        //离线 
        
        block=int(pow(n,0.66666));
        for(int i=1;i<=n;i++)st[i]=(i-1)/block+1;
        sort(q+1,q+qlen+1,cmp);
        
        ans=0;
        solve();
        
        for(int i=1;i<=qlen;i++)printf("%d
    ",as[i]);
        return 0;
    }
  • 相关阅读:
    PSFTP使用简单教程
    JavaMail应用--通过javamail API实现在代码中发送邮件功能
    java常用数据类型转换
    自己封装的Java excel数据读取方法
    java怎样实现重载一个方法
    怎样做好测试保证交付产品质量
    软件测试之测试用例颗粒度问题
    Python 一句命令启动一个web服务器
    ansible 模块之在学习--lineinfile
    centos 7 安装sql 审核工具 inception + archer
  • 原文地址:https://www.cnblogs.com/AKCqhzdy/p/7772883.html
Copyright © 2011-2022 走看看