• CF848C Goodbye Souvenir


    此题解仅用于搞笑。

    题解

    这道题目被我们各种题意转换之后就是一个二维数点,带修改的。

    由于我 ( ext{cdq}) 不太熟练,不知道带修改的该怎么搞,树套树的空间又被卡了(好像有人过了,反正我过不了),然后就决定学习一下 ( ext{KD-Tree}) 来搞二维数点。

    然后我就写了一棵 ( ext{KD-Tree}) ,交了几发才过,很快啊,比树套树快。

    代码

    #pragma GCC optimize(2)
    
    #include<bits/stdc++.h>
    using namespace std;
    const int N=1e5+5,K=2;
    const int INF=1e9+7;
    const double alpha=0.83;
    int n,m,a[N],lst[N];
    set<int> bag[N];
    struct Point{int x[K];long long val;}p[N*7];
    int cmp_data;
    bool cmp(Point a,Point b){
    	if(a.x[cmp_data]!=b.x[cmp_data])
    	return a.x[cmp_data]<b.x[cmp_data];
    	return false;
    }
    struct KD_Tree{
    	int rt,tot,top,rub[N*7];
    	struct Node{
    		int ls,rs,size;long long sum;Point p;
    		int div,minn[K],maxn[K];
    	}tr[N*7];
    	KD_Tree(){
    		for(int i=0;i<K;++i) tr[0].minn[i]=INF;
    		for(int i=0;i<K;++i) tr[0].maxn[i]=-INF;
    	}
    	int newnode(){
    		if(top) return rub[top--];
    		return ++tot;
    	}
    	void recycle(int u){
    		tr[u]=tr[0],rub[++top]=u;
    	}
    	void up(int u){
    		tr[u].size=tr[tr[u].ls].size+tr[tr[u].rs].size+1;
    		tr[u].sum=tr[tr[u].ls].sum+tr[tr[u].rs].sum+tr[u].p.val;
    		for(int i=0;i<K;++i) tr[u].minn[i]=tr[u].maxn[i]=tr[u].p.x[i];
    		for(int i=0;i<K;++i){
    			tr[u].minn[i]=min(tr[u].minn[i],tr[tr[u].ls].minn[i]);
    			tr[u].minn[i]=min(tr[u].minn[i],tr[tr[u].rs].minn[i]);
    			tr[u].maxn[i]=max(tr[u].maxn[i],tr[tr[u].ls].maxn[i]);
    			tr[u].maxn[i]=max(tr[u].maxn[i],tr[tr[u].rs].maxn[i]);
    		}
    	}
    	int build(int l,int r,Point p[]){
    		if(l>r) return 0;
    		int u=newnode(),mid=(l+r)>>1;
    		tr[u].div=rand()%2,cmp_data=tr[u].div,nth_element(p+l,p+mid,p+r+1,cmp),tr[u].p=p[mid];
    		tr[u].ls=build(l,mid-1,p),tr[u].rs=build(mid+1,r,p);
    		return up(u),u;
    	}
    	bool check(int u){
    		return alpha*tr[u].size<=max(tr[tr[u].ls].size,tr[tr[u].rs].size);
    	}
    	void dfs(int u,int &cnt){
    		if(!u) return ;
    		dfs(tr[u].ls,cnt),dfs(tr[u].rs,cnt);
    		p[++cnt]=tr[u].p,recycle(u);
    	}
    	void rebuild(int &u){
    		int cnt=0;dfs(u,cnt),u=build(1,cnt,p);
    	}
    	void insert(int &u,Point p){
    		if(!u) return u=newnode(),tr[u].p=p,up(u);
    		if(p.x[tr[u].div]<=tr[u].p.x[tr[u].div])
    		insert(tr[u].ls,p);else insert(tr[u].rs,p);
    		if(check(u)) rebuild(u);
    		return up(u);
    	}
    	long long query(int u,int xl[],int xr[]){
    		if(!u) return 0;
    		for(int i=0;i<K;++i) if(tr[u].minn[i]>xr[i]||tr[u].maxn[i]<xl[i]) return 0;
    		int flag1=1,flag2=1;
    		for(int i=0;i<K;++i) flag1&=(xl[i]<=tr[u].minn[i]&&tr[u].maxn[i]<=xr[i]);
    		if(flag1) return tr[u].sum;
    		for(int i=0;i<K;++i) flag2&=(xl[i]<=tr[u].p.x[i]&&tr[u].p.x[i]<=xr[i]);
    		return flag2*tr[u].p.val+query(tr[u].ls,xl,xr)+query(tr[u].rs,xl,xr);
    	}
    }t;
    int main(){
    	srand(time(NULL));
    	cin>>n>>m;
    	for(int i=1;i<=n;++i){
    		Point p;
    		scanf("%d",&a[i]),bag[a[i]].insert(i);
    		set<int>::iterator tmp=bag[a[i]].find(i);
    		if(tmp!=bag[a[i]].begin())
    		p.x[1]=*tmp,tmp--,lst[i]=p.x[0]=*tmp;
    		else p.x[1]=*tmp,lst[i]=p.x[0]=0;
    		p.val=p.x[1]-p.x[0],t.insert(t.rt,p);
    	}
    	for(int i=1;i<=m;++i){
    		int opt,x,y;
    		scanf("%d%d%d",&opt,&x,&y);
    		if(opt==2){
    			int xl[K],xr[K];
    			xl[0]=xl[1]=x,xr[0]=xr[1]=y;
    			printf("%lld
    ",t.query(1,xl,xr));
    		}
    		else{
    			Point p;set<int>::iterator tmp;
    			tmp=bag[a[x]].find(x);
    			if(tmp!=bag[a[x]].end()){
    				p.x[0]=lst[*tmp],p.x[1]=*tmp;
    				p.val=p.x[0]-p.x[1],t.insert(t.rt,p);
    			}
    			tmp=bag[a[x]].upper_bound(x);
    			if(tmp!=bag[a[x]].end()){
    				p.x[0]=lst[*tmp],p.x[1]=*tmp;
    				p.val=p.x[0]-p.x[1],t.insert(t.rt,p);
    			}
    			tmp=bag[y].upper_bound(x);
    			if(tmp!=bag[y].end()){
    				p.x[0]=lst[*tmp],p.x[1]=*tmp;
    				p.val=p.x[0]-p.x[1],t.insert(t.rt,p);
    			}
    			bag[a[x]].erase(bag[a[x]].find(x)),bag[y].insert(x);
    			tmp=bag[y].find(x);
    			if(tmp!=bag[y].end()){
    				int fuck=*tmp;
    				if(tmp!=bag[y].begin())
    				p.x[1]=*tmp,tmp--,lst[fuck]=p.x[0]=*tmp;
    				else p.x[1]=*tmp,lst[fuck]=p.x[0]=0;
    				p.val=p.x[1]-p.x[0],t.insert(t.rt,p);
    			}
    			tmp=bag[y].upper_bound(x);
    			if(tmp!=bag[y].end()){
    				int fuck=*tmp;
    				if(tmp!=bag[y].begin())
    				p.x[1]=*tmp,tmp--,lst[fuck]=p.x[0]=*tmp;
    				else p.x[1]=*tmp,lst[fuck]=p.x[0]=0;
    				p.val=p.x[1]-p.x[0],t.insert(t.rt,p);
    			}
    			tmp=bag[a[x]].upper_bound(x);
    			if(tmp!=bag[a[x]].end()){
    				int fuck=*tmp;
    				if(tmp!=bag[a[x]].begin())
    				p.x[1]=*tmp,tmp--,lst[fuck]=p.x[0]=*tmp;
    				else p.x[1]=*tmp,lst[fuck]=p.x[0]=0;
    				p.val=p.x[1]-p.x[0],t.insert(t.rt,p);
    			}
    			a[x]=y;
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    【codeforces 766C】Mahmoud and a Message
    【codeforces 766D】Mahmoud and a Dictionary
    【b704 && BZOJ 1999】树网的核
    优秀Java程序员必须了解的GC工作原理
    Apparatus, system, and method for automatically minimizing real-time task latency and maximizing non-real time task throughput
    NODEJS网站
    day63-webservice 01.cxf介绍
    04.webservice客户端调用
    03.WSDL分析
    02.socket实现远程调用
  • 原文地址:https://www.cnblogs.com/Point-King/p/14679839.html
Copyright © 2020-2023  润新知