zoukankan      html  css  js  c++  java
  • [BZOJ2120]数颜色(莫队算法)

    Description

    墨墨购买了一套N支彩色画笔(其中有些颜色可能相同),摆成一排,你需要回答墨墨的提问。墨墨会像你发布如下指令: 1、 Q L R代表询问你从第L支画笔到第R支画笔中共有几种不同颜色的画笔。 2、 R P Col 把第P支画笔替换为颜色Col。为了满足墨墨的要求,你知道你需要干什么了吗?

    带修改莫队,给每个询问加一个权值时间tim,询问的时候让时光回溯

    Code

    #include <cstdio>
    #include <algorithm>
    #include <cmath>
    #define N 10010
    using namespace std;
    
    int n,m,col[N],now[N],bl[N],Tim,cnt,Ans[N],sum,Scol[N*100],l,r; 
    struct change{
    	int p,v,pre;
    	change(){}
    	change(int a,int b,int c):p(a),v(b),pre(c){}
    }c[N/10];
    struct query{
    	int tim,l,r,id;
    	query(){}
    	query(int a,int b,int c,int d):l(a),r(b),tim(c),id(d){}
    	friend bool operator <(query a,query b){
    		return (bl[a.l]==bl[b.l])?(a.r==b.r?a.tim<b.tim:a.r<b.r):a.l<b.l;
    	}
    }q[N];
    
    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*10+ch-'0';ch=getchar();}
        return x*f;
    }
    
    void upd(int x,int d){
    	Scol[x]+=d;
    	if(d>0) sum+=(Scol[x]==1);
    	else sum-=(Scol[x]==0);
    }
    void go(int x,int d){
    	if(l<=x&&x<=r) upd(d,1),upd(col[x],-1);
    	col[x]=d;
    }
    
    int main(){
    	n=read(),m=read();int blo=sqrt(n);
    	for(int i=1;i<=n;++i) col[i]=now[i]=read(),bl[i]=i/blo+1;
    	for(int i=1;i<=m;++i){
    		char ch;for(ch=getchar();ch!='Q'&&ch!='R';ch=getchar());
    		int x=read(),y=read();
    		if(ch=='Q') q[++cnt]=query(x,y,Tim,cnt);
    		else c[++Tim]=change(x,y,now[x]),now[x]=y;
    	}
    	sort(q+1,q+cnt+1);
    	for(int i=1,t=0;i<=cnt;++i){
    		for(;t<q[i].tim;t++) go(c[t+1].p,c[t+1].v);
    		for(;t>q[i].tim;t--) go(c[t].p,c[t].pre);
    		for(;l<q[i].l;l++) upd(col[l],-1);
    		for(;l>q[i].l;l--) upd(col[l-1],1);
    		for(;r<q[i].r;r++) upd(col[r+1],1);
    		for(;r>q[i].r;r--) upd(col[r],-1);
    		Ans[q[i].id]=sum;
    	}
    	for(int i=1;i<=cnt;printf("%d
    ",Ans[i++]));
    	return 0;
    }
    
  • 相关阅读:
    Linux 安装中文man手册
    centos6.9使用NTFS-3G挂载ntfs文件系统
    Linux基础知识之挂载详解(mount,umount及开机自动挂载)
    技术点总结
    SQL 分组后获取其中一个字段最大值的整条记录 【转载】
    线程池之ThreadPool类与辅助线程
    Task.Run使用默认线程池
    VS生成事件
    线程池之ThreadPoolExecutor使用
    Sql笔记
  • 原文地址:https://www.cnblogs.com/void-f/p/9090490.html
Copyright © 2011-2022 走看看