zoukankan      html  css  js  c++  java
  • BZOJ2120:数颜色(分块版)

    浅谈分块:https://www.cnblogs.com/AKMer/p/10369816.html

    题目传送门:https://lydsy.com/JudgeOnline/problem.php?id=2120

    树套树做法:https://www.cnblogs.com/AKMer/p/10189008.html

    对于每个块维护块内(pre)上升的数组即可,每次查找直接(lower) (bound)一下,其它的跟树套树版的没什么区别。

    时间复杂度:(O(nlogsqrt{n}+msqrt{n}logsqrt{n}))

    空间复杂度:(O(n))

    代码如下:

    #include <set>
    #include <cmath>
    #include <cstdio>
    #include <algorithm>
    using namespace std;
    
    const int maxn=1e4+5,maxv=1e6+5;;
    
    char s[5];
    int n,m,block;
    set<int>pos[maxv];
    set<int>::iterator it;
    int L[105],R[105],f[105][105];
    int col[maxn],bel[maxn],pre[maxv],now[maxv];
    
    int read() {
    	int x=0,f=1;char ch=getchar();
    	for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;
    	for(;ch>='0'&&ch<='9';ch=getchar())x=x*10+ch-'0';
    	return x*f;
    }
    
    void build(int id) {
    	for(int i=L[id];i<=R[id];i++)
    		f[id][i-L[id]+1]=pre[i];
    	sort(f[id]+1,f[id]+R[id]-L[id]+2);
    }
    
    int main() {
    	n=read(),m=read(),block=sqrt(n);
    	for(int i=1;i<=n;i++) {
    		col[i]=read(),bel[i]=(i-1)/block+1;
    		if(pos[col[i]].empty())
    			pos[col[i]].insert(0),pos[col[i]].insert(n+1);
    		if(bel[i]!=bel[i-1])R[bel[i-1]]=i-1,L[bel[i]]=i;
    		pre[i]=now[col[i]],now[col[i]]=i,pos[col[i]].insert(i);
    	}R[bel[n]]=n;
    	for(int i=1;i<=bel[n];i++)build(i);
    	while(m--) {
    		scanf("%s",s+1);
    		if(s[1]=='Q') {
    			int ans=0,l=read(),r=read();
    			if(bel[l]==bel[r]) {
    				for(int i=l;i<=r;i++)if(pre[i]<l)ans++;
    			}
    			else {
    				for(int i=l;i<=R[bel[l]];i++)if(pre[i]<l)ans++;
    				for(int i=L[bel[r]];i<=r;i++)if(pre[i]<l)ans++;
    				for(int i=bel[l]+1;i<bel[r];i++)
    					ans+=lower_bound(f[i]+1,f[i]+R[i]-L[i]+2,l)-f[i]-1;
    			}
    			printf("%d
    ",ans);
    		}
    		else {
    			int p=read(),c=read(),tmp=col[p],l,r;
    			if(pos[c].empty())pos[c].insert(0),pos[c].insert(n+1);
    			pos[tmp].erase(pos[tmp].find(p));
    			it=pos[tmp].lower_bound(p);
    			if(it!=pos[tmp].end()&&it!=pos[tmp].begin())
    				r=*it,it--,l=*it,pre[r]=l,build(bel[r]);
    			it=pos[c].lower_bound(p);
    			if(it!=pos[c].end())pre[*it]=p,build(bel[*it]);
    			if(it!=pos[c].begin())it--,pre[p]=*it,build(bel[p]);
    			pos[c].insert(p);
    			col[p]=c;
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    python操作excel表格
    重学Java
    重学Java
    重学Java
    重学Java
    重学Java
    博客园自定义主题及目录组件
    重学Java
    修改 Eclipse 背景颜色的高级方法
    dbf转excel
  • 原文地址:https://www.cnblogs.com/AKMer/p/10373457.html
Copyright © 2011-2022 走看看