zoukankan      html  css  js  c++  java
  • bzoj 2120: 数颜色【带修改莫队】

    比较裸的带修莫队,对每个修改操作记一下它修改的位置修改前的颜色
    然后正常莫队,每次对修改操作时间倒流一下即可

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    const int N=200005;
    int n,m,bl[N],la[N],co[1000005],ta,tb,v[N],con[1000005],ans[N],nw;
    char s[10];
    struct qw
    {
    	int p,c,pr;
    }a[N];
    struct qwe
    {
    	int l,r,id,ti;
    }b[N];
    bool cmp(const qwe &a,const qwe &b)
    {
    	return bl[a.l]<bl[b.l]||(bl[a.l]==bl[b.l]&&a.r<b.r);
    }
    int read()
    {
    	int r=0,f=1;
    	char p=getchar();
    	while(p>'9'||p<'0')
    	{
    		if(p=='-')
    			f=-1;
    		p=getchar();
    	}
    	while(p>='0'&&p<='9')
    	{
    		r=r*10+p-48;
    		p=getchar();
    	}
    	return r*f;
    }
    void clc(int x)
    {
    	if(v[x])
    	{
    		if(!--con[co[x]])
    			nw--;
    	}
    	else if(++con[co[x]]==1)
    		nw++;
    	v[x]^=1;
    }
    void change(int x,int c)
    {
    	if(v[x])
    	{
    		clc(x);
    		co[x]=c;
    		clc(x);
    	}
    	else
    		co[x]=c;
    }
    int main()
    {
    	n=read(),m=read();
    	for(int i=1;i<=n;i++)
    		la[i]=co[i]=read();
    	for(int i=1;i<=m;i++)
    	{
    		scanf("%s",s);
    		int x=read(),y=read();
    		if(s[0]=='R')
    		{
    			a[++ta].p=x;
    			a[ta].c=y;
    			a[ta].pr=la[x];//记录更改之前的颜色
    			la[x]=y;
    		}
    		else
    		{
    			b[++tb].l=x;
    			b[tb].r=y;
    			b[tb].id=tb;
    			b[tb].ti=ta;//记录他之前的离他最近的操作
    		}
    	}
    	int kuai=sqrt(n);
    	for(int i=1;i<=n;i++)
    		bl[i]=(i-1)/kuai+1;
    	sort(b+1,b+tb+1,cmp);
    	int l=1,r=1;
    	clc(l);
    	for(int i=1;i<=tb;i++)
    	{
    		for(int j=b[i-1].ti+1;j<=b[i].ti;j++)
    			change(a[j].p,a[j].c);
    		for(int j=b[i-1].ti;j>b[i].ti;j--)
    			change(a[j].p,a[j].pr);
    		while(l<b[i].l)  
    			clc(l++);
    		while(l>b[i].l)  
    			clc(--l);
    		while(r<b[i].r)  
    			clc(++r);
    		while(r>b[i].r)  
    			clc(r--);
    		ans[b[i].id]=nw;
    	}
    	for(int i=1;i<=tb;i++)
    		printf("%d
    ",ans[i]);
    	return 0;
    }
    
  • 相关阅读:
    leetcode165
    leetcode63
    leetcode92
    leetcode86
    捣鼓Haskell
    递归操作链表
    treap(堆树)
    贪心策略 — 分数背包
    LeetCode.21
    LeetCode.94
  • 原文地址:https://www.cnblogs.com/lokiii/p/9712820.html
Copyright © 2011-2022 走看看