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

    原文链接https://www.cnblogs.com/zhouzhendong/p/BZOJ2120.html

    题目传送门 - BZOJ2120

    题意

      给定一个长度为 $n$ 的序列 $a$ ,有 $m$ 次操作,每次操作可能是如下两种类型之一:

      1. 询问区间不同值的个数。

      2. 修改一个 $a_i$ 。

      对于每一次询问,输出结果。

      $n,mleq 10000, 1leq a_ileq10^6$ 

    题解

      带修莫队裸题。

      打错一个变量找了20分钟。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    const int N=10005,M=1000005;
    int n,m,Qcnt=0,Ocnt=0;
    int c[N],dc[N],k[N];
    int tax[M],tot=0;
    struct Query{
    	int L,R,id,ans;
    	Query(){}
    	Query(int _L,int _R,int _id){
    		L=_L,R=_R,id=_id;
    	}
    }Q[N];
    struct Operation{
    	int x,v1,v2,id;
    	Operation(){}
    	Operation(int _x,int _v1,int _v2,int _id){
    		x=_x,v1=_v1,v2=_v2,id=_id;
    	}
    }O[N];
    bool cmp(Query a,Query b){
    	if (k[a.L]!=k[b.L])
    		return k[a.L]<k[b.L];
    	if (k[a.R]!=k[b.R])
    		return k[a.R]<k[b.R];
    	return a.id<b.id;
    }
    bool cmpid(Query a,Query b){
    	return a.id<b.id;
    }
    int L=1,R=0,t=0;
    void update(int t){
    	int x=O[t].v1,y=O[t].v2,id=O[t].x;
    	if (c[id]!=x)
    		swap(x,y);
    	if (L<=id&&id<=R){
    		tot-=(--tax[x])==0;
    		tot+=(tax[y]++)==0;
    	}
    	c[id]=y;
    }
    int main(){
    	scanf("%d%d",&n,&m);
    	for (int i=1;i<=n;i++)
    		scanf("%d",&c[i]),dc[i]=c[i];
    	for (int i=1;i<=m;i++){
    		char ch[2];
    		int x,y;
    		scanf("%s%d%d",ch,&x,&y);
    		if (ch[0]=='Q')
    			Q[++Qcnt]=Query(min(x,y),max(x,y),i);
    		else {
    			O[++Ocnt]=Operation(x,y,dc[x],i);
    			dc[x]=y;
    		}
    	}
    	for (int i=1;i<=n;i++)
    		k[i]=(i-1)/400;
    	sort(Q+1,Q+Qcnt+1,cmp);
    	memset(tax,0,sizeof tax);
    	O[0].id=0,O[Ocnt+1].id=m+1;
    	for (int i=1;i<=Qcnt;i++){
    		while (L<Q[i].L)
    			tot-=(--tax[c[L++]])==0;
    		while (L>Q[i].L)
    			tot+=(tax[c[--L]]++)==0;
    		while (R<Q[i].R)
    			tot+=(tax[c[++R]]++)==0;
    		while (R>Q[i].R)
    			tot-=(--tax[c[R--]])==0;
    		while (O[t+1].id<Q[i].id)
    			update(++t);
    		while (O[t].id>Q[i].id)
    			update(t--);
    		Q[i].ans=tot;
    	}
    	sort(Q+1,Q+Qcnt+1,cmpid);
    	for (int i=1;i<=Qcnt;i++)
    		printf("%d
    ",Q[i].ans);
    	return 0;
    }
    

      

  • 相关阅读:
    并发编程之多线程(理论部分)
    基于TCP和UDP的socket
    ajax笔记 显示出所城市名称 ShowCity.aspx Html代码
    蒸饭的纱布
    ajax 笔记--不刷新实现简单的留言版 guestBook
    从表的第几条取到第几条记录
    在asp.net添加数据到XML里去
    ajax 笔记-- 写了一个不用刷新就能实现--用户名验证的例子
    今天生日
    ajax 笔记不用刷新实现数据的分页显示
  • 原文地址:https://www.cnblogs.com/zhouzhendong/p/BZOJ2120.html
Copyright © 2011-2022 走看看