zoukankan      html  css  js  c++  java
  • P1903 数颜色

    题目

    带修莫队题。

    在询问上多加一个变量,记录是在那次修改之后的。

    然后暴力修改。

    就没了。

    不过有一些修改的小技巧

    #include<cstdio>
    #include<algorithm>
    #include<iostream>
    #include<cmath>
    using namespace std;
    const int manx=50010;
    int read()//千万不要用快读
    {
    	char c=getchar();
    	int res=0;
    	while(c>'9'||c<'0')	c=getchar();
    	while(c>='0'&&c<='9')
    	{
    		res=(res<<3)+(res<<1)+c-'0';	
    		c=getchar();
    	}
    	return res;
    }
    bool judge()//我是贞德毒瘤
    {
    	char c=getchar();
    	while(c<'A'||c>'Z')	c=getchar();
    	if(c=='Q')	return false;
    	return true;
    }
    struct node
    {
    	int l,r;
    	int t;//哪一次修改之后
    	int pos;
    };
    int qua;
    bool compare(const node &a,const node &b)
    {
    	return a.l/qua==b.l/qua ? a.r<b.r : a.l < b.l;
    }
    node query[manx];
    int cha[manx][2],t1,t2;//t1为修改次数,t2为询问次数
    int base[manx];
    int cont[manx<<5];
    int ans[manx];
    int l=1,r=0;
    int answer;//简单的莫队一些所需要的
    void osc(int t)//调整时间
    {
    	while(t1<t)
    	{
    		t1++;
    		if(cha[t1][0]>=l&&cha[t1][0]<=r)
    		{
    			cont[cha[t1][1]]+=1,cont[base[cha[t1][0]]]-=1;//如果在当前莫队的区间内,就要单独处理
    			if(cont[cha[t1][1]]==1)	answer+=1;
    			if(cont[base[cha[t1][0]]]==0)	answer-=1;
    		}
    		swap(cha[t1][1],base[cha[t1][0]]);//这里便是一个小技巧,直接交换,我们可以自己稍微模拟一下233,这样是不改变正确性的。
    	}
    	while(t1>t)//删除同理,很具有对称性
    	{
    		swap(cha[t1][1],base[cha[t1][0]]);
    		if(cha[t1][0]>=l&&cha[t1][0]<=r)
    		{
    			cont[cha[t1][1]]-=1,cont[base[cha[t1][0]]]+=1;	
    			if(cont[cha[t1][1]]==0)	answer-=1;
    			if(cont[base[cha[t1][0]]]==1)	answer+=1;
    		}
    		t1--;
    	}
    	return ;
    }
    void add(int pos)
    {
    	if(!cont[base[pos]])	answer+=1;
    	cont[base[pos]]+=1;
    	return;
    }//简单的单点修改
    void del(int pos)
    {
    	cont[base[pos]]-=1;
    	if(!cont[base[pos]])	answer-=1;
    	return ;
    }
    int main()
    {
    	int n=read(),m=read();
    	qua=pow(n,0.5);
    	for(int i=1;i<=n;i++)
    		base[i]=read();
    	int a,b;
    	for(int i=1;i<=m;i++)
    	{
    		bool f=judge();
    		a=read(),b=read();
    		if(f)	
    			cha[++t1][0]=a,cha[t1][1]=b;
    		else
    			query[++t2].l=a,query[t2].r=b,query[t2].t=t1,query[t2].pos=t2;
    	}
    	sort(query+1,query+t2+1,compare);
    	t1=0;
    	for(int i=1;i<=t2;i++)
    	{
    		osc(query[i].t);//除了这一句和上面录入数据不一样,其他和普通莫队就是一样了233
    		while(r<query[i].r)
    			add(++r);
    		while(r>query[i].r)
    			del(r--);
    		while(l<query[i].l)
    			del(l++);
    		while(l>query[i].l)
    			add(--l);
    		ans[query[i].pos]=answer;
    	}
    	for(int i=1;i<=t2;i++)
    		printf("%d
    ",ans[i]);
    }
    
  • 相关阅读:
    通用应用程序设计
    咫尺与天涯
    SQL SERVER 自定义函数 split
    asp.net 页面实践执行顺序
    asp.net UpdatePanel 不能局部刷新问题汇总
    DataGrid GridView 单页javascript 表头排序
    存储过程分页方案
    数据库名、数据表名、字段名、主键、标识列相关查询
    c# web 缓存管理
    js笔记---拖动元素
  • 原文地址:https://www.cnblogs.com/Lance1ot/p/9200945.html
Copyright © 2011-2022 走看看