zoukankan      html  css  js  c++  java
  • SP32952 ADAFTBLL

    题意

    SP32952 ADAFTBLL - Ada and Football

    解答

    一看到统计出现次数就能想到莫队。

    于是树上带修莫队,树分块版莫队可以解决。

    统计答案也很简单。

    代码:

    #include <bits/stdc++.h>
    using namespace std;
    template <typename T>
    inline void read(T &x){
    	x=0;char ch=getchar();bool f=false;
    	while(!isdigit(ch)){if(ch=='-'){f=true;}ch=getchar();}
    	while(isdigit(ch)){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
    	x=f?-x:x;
    	return ;
    }
    template <typename T>
    inline void write(T x){
    	if(x<0) putchar('-'),x=-x;
    	if(x>9) write(x/10);
    	putchar(x%10^48);
    	return ;
    }
    #define ll long long
    const int N=1e5+5,INF=1e9+7;
    struct Query{
        int u,v,t,id;
        Query(int u=0,int v=0,int t=0,int id=0):u(u),v(v),t(t),id(id){}
    }Q[N];
    
    struct Change{
        int u,las,nex;
        Change(int u=0,int las=0,int nex=0):u(u),las(las),nex(nex){}
    }C[N];
    int val[N],w[N],fa[N],dep[N],son[N],sta[N];
    int siz[N],top[N],bl[N],a[N];
    ll sum[N];
    bool vis[N];
    int n,m,q,Top,idx,cnt1,cnt2,block;
    ll res,Ans[N];
    vector<int> vec[N];
    void dfs1(int u,int f){
    	int now=Top;
    	sta[++Top]=u,fa[u]=f,dep[u]=dep[f]+1,siz[u]=1;//压入栈和更新信息 
    	for(auto v:vec[u]){
    		if(v==f) continue;
    		dfs1(v,u);
    		if(Top-now>block){//如果里面的点多于 B 个 
    			idx++;//块编号 
    			while(Top!=now) bl[sta[Top--]]=idx;//更新节点所属块 
    		}
    		siz[u]+=siz[v];
    		if(siz[v]>siz[son[u]]) son[u]=v; 
    	}
    	return ;
    }
    void dfs2(int u,int f){//树剖预处理 
    	top[u]=f;
    	if(!son[u]) return ;
    	dfs2(son[u],f);
    	for(auto v:vec[u]){
    		if(v==fa[u]||v==son[u]) continue;
    		dfs2(v,v);
    	}
    	return ;
    }
    inline int QueryLca(int u,int v){//查询lca 
    	while(top[u]!=top[v]){
    		if(dep[top[u]]<dep[top[v]]) swap(u,v);
    		u=fa[top[u]];
    	}
    	if(dep[u]<dep[v]) return u;
    	return v;
    }
    inline bool cmp(Query a,Query b){//莫队排序 
    	if(bl[a.u]==bl[b.u]){
    		if(bl[a.v]==bl[b.v]) return a.t<b.t;
    		return bl[a.v]<bl[b.v];
    	}
    	return bl[a.u]<bl[b.u];
    }
    inline void Add(int u){//更新添加a[u]的影响 
    	res-=sum[u]*(sum[u]-1);
    	sum[u]++;
    	res+=sum[u]*(sum[u]-1);
    	return ;
    }
    inline void Del(int u){//更新删掉a[u]的影响 
    	res-=sum[u]*(sum[u]-1);
    	sum[u]--;
    	res+=sum[u]*(sum[u]-1);
    	return ;
    }
    inline void Update(int u){//把u这个点取反的影响(用变不用,不用变用) 
    	if(vis[u]) Del(a[u]),vis[u]=false;
    	else Add(a[u]),vis[u]=true;
    	return ;
    }
    inline void Modify(int u,int t){//把u这个点的颜色换成t的影响 
    	if(vis[u]) Del(a[u]),Add(t);
    	a[u]=t;
    	return ;
    }
    inline void Move(int u,int v){//把u->v这条路径的更新了 
    	if(dep[u]<dep[v]) swap(u,v);
    	while(dep[u]>dep[v]) Update(u),u=fa[u];
    	while(u!=v) Update(u),Update(v),u=fa[u],v=fa[v];
    	return ;
    }
    int main(){
    	read(n),read(q);
    	block=pow(n,2.0/3);
    	for(int i=1;i<=n;i++) read(a[i]),sta[i]=a[i];//a是最初的颜色 
    	for(int i=1;i<n;i++){//建图 
    		int u,v;read(u),read(v);u++,v++;
    		vec[u].push_back(v),vec[v].push_back(u);
    	}
    	for(int i=1;i<=q;i++){
    		int op,u,v;
    		read(op),read(u),read(v);
    		if(op==1) u++,C[++cnt1]=Change(u,sta[u],v),sta[u]=v;//操作,sta是当前的颜色 
    		else u++,v++,++cnt2,Q[cnt2]=Query(u,v,cnt1,cnt2);//l,r,t,id
    	}
    	memset(sta,0,sizeof(sta));
    	dfs1(1,0),dfs2(1,1);//分块和LCA预处理 
    	while(Top>0) bl[sta[Top--]]=idx;//分完块 
    	sort(Q+1,Q+cnt2+1,cmp);//莫队排序 
    	int u,v,t;
    	u=v=1,t=0;
    	Update(1);//初始化第一个点 
    	for(int i=1;i<=cnt2;i++){//处理询问 
    		while(t<Q[i].t) Modify(C[t+1].u,C[t+1].nex),t++;//修正时间 
    		while(t>Q[i].t) Modify(C[t].u,C[t].las),--t;
    		Update(QueryLca(u,v));//两个LCA在这里要单独讨论 
    		if(u!=Q[i].u) Move(u,Q[i].u),u=Q[i].u;//u更新到u` 
    		if(v!=Q[i].v) Move(v,Q[i].v),v=Q[i].v;//v更新到v` 
    		Update(QueryLca(u,v));//讨论 
    		Ans[Q[i].id]=res/2;
    	}
    	for(int i=1;i<=cnt2;i++) write(Ans[i]),putchar('
    '); 
    	return 0; 
    }
    

    这道题从 0 开始编号...结果分别加1的时候把权值也加上去了..

  • 相关阅读:
    MVC模式-----struts2框架(2)
    MVC模式-----struts2框架
    html的<h>标签
    jsp脚本元素
    LeetCode "Paint House"
    LeetCode "Longest Substring with At Most Two Distinct Characters"
    LeetCode "Graph Valid Tree"
    LeetCode "Shortest Word Distance"
    LeetCode "Verify Preorder Sequence in Binary Search Tree"
    LeetCode "Binary Tree Upside Down"
  • 原文地址:https://www.cnblogs.com/Akmaey/p/14696010.html
Copyright © 2011-2022 走看看