zoukankan      html  css  js  c++  java
  • [BZOJ2120]数颜色

    bzoj
    luogu

    sol

    树状数组套线段数题解。
    对每个位置记一个(last_i),表示与这个位置颜色相同的前一个位置。若这个位置上的颜色是第一次出现则(last_i=0)
    那么查询的时候就查询所有(Lle ile R)(last_i<L)的个数就行了。
    问题转化为一个二维数点问题,静态主席树动态树套树。
    因为修改会影响到前趋后继什么的,所以对每个颜色开一个(set)然后大力讨论一波。

    code

    #include<cstdio>
    #include<algorithm>
    #include<set>
    using namespace std;
    int gi()
    {
    	int x=0,w=1;char ch=getchar();
    	while ((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
    	if (ch=='-') w=0,ch=getchar();
    	while (ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
    	return w?x:-x;
    }
    const int N = 1e4+5;
    struct segment_tree{int ls,rs,v;}t[N*150];
    int n,m,a[N],lst[N],rt[N],tot;
    set<int>S[N*100];
    set<int>::iterator it,itt;
    void Modify(int &x,int l,int r,int p,int v)
    {
    	if (!x) x=++tot;t[x].v+=v;
    	if (l==r) return;int mid=l+r>>1;
    	if (p<=mid) Modify(t[x].ls,l,mid,p,v);
    	else Modify(t[x].rs,mid+1,r,p,v);
    }
    int Query(int x,int l,int r,int ql,int qr)
    {
    	if (!x||l>=ql&&r<=qr) return t[x].v;
    	int mid=l+r>>1;
    	if (qr<=mid) return Query(t[x].ls,l,mid,ql,qr);
    	if (ql>mid) return Query(t[x].rs,mid+1,r,ql,qr);
    	return Query(t[x].ls,l,mid,ql,qr)+Query(t[x].rs,mid+1,r,ql,qr);
    }
    void PreModify(int k,int p,int v)
    {
    	for (int i=k+1;i<=n;i+=i&-i)
    		Modify(rt[i],1,n,p,v);//树状数组的下标必须从1开始,所以这里选择加了一个1
    }
    int main()
    {
    	n=gi();m=gi();
    	for (int i=1;i<=n;++i) a[i]=gi(),S[a[i]].insert(i);
    	for (int i=1;i<=n;++i)
    	{
    		it=S[a[i]].find(i);
    		if (it!=S[a[i]].begin()) PreModify(*--it,i,1);
    		else PreModify(0,i,1);
    	}
    	while (m--)
    	{
    		char ch=getchar();
    		while (ch!='Q'&&ch!='R') ch=getchar();
    		if (ch=='Q')
    		{
    			int l=gi(),r=gi(),res=0;
    			for (int i=l;i;i-=i&-i)
    				res+=Query(rt[i],1,n,l,r);
    			printf("%d
    ",res);
    		}
    		else
    		{
    			int i=gi();
    			it=S[a[i]].find(i);
    			itt=it;--itt;
                if (it!=S[a[i]].begin()) PreModify(*itt,*it,-1);
    			else PreModify(0,*it,-1);
                itt=it;++itt;
                if (itt!=S[a[i]].end())
    			{
    				PreModify(*it,*itt,-1);
    				if (it!=S[a[i]].begin()) PreModify(*--it,*itt,1);
    				else PreModify(0,*itt,1);
    			}
    			S[a[i]].erase(i);
    			a[i]=gi();
    			S[a[i]].insert(i);
    			it=S[a[i]].find(i);
    			itt=it;--itt;
    			if (it!=S[a[i]].begin()) PreModify(*itt,*it,1);
    			else PreModify(0,*it,1);
    			itt=it;++itt;
    			if (itt!=S[a[i]].end())
    			{
    				PreModify(*it,*itt,1);
    				if (it!=S[a[i]].begin()) PreModify(*--it,*itt,-1);
    				else PreModify(0,*itt,-1);
    			}
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    HLG 1522 子序列的和【队列的应用】
    POJ 3273 Monthly Expense【二分】
    HDU 4004 The Frog's Games 【二分】
    POJ 2001 Shortest Prefixes【第一棵字典树】
    POJ 2823 Sliding Window【单调对列经典题目】
    HDU 1969 Pie 【二分】
    POJ 3125 Printer Queue【暴力模拟】
    POJ 3250 Bad Hair Day【单调栈】
    字典树【模板】
    验证码 Code
  • 原文地址:https://www.cnblogs.com/zhoushuyu/p/8568495.html
Copyright © 2011-2022 走看看