zoukankan      html  css  js  c++  java
  • codechef TREECNT2

    (gcd(l...r))表示(l...r)路径上的(gcd)
    (ans=[gcd(l...r)]=sum_{d|gcd(l...r)}vu(d))
    (=sum_{i=1}^{1000000}vu(d)sum_{d|gcd(l...r)}1)
    一个显然的想法:注意到只有(vu(d) eq 0)且被一个(gcd(l...r))整除的(d)才有用。
    所以可以把所有(gcd(l...r))的约数(d)拿出来,建立一新树(T'),把边权为(d)的倍数的边插入(T'),然后统计每个连通块大小的二次方和。
    由于最多会插入(2^d)条边,所以一次询问(O(n2^d))
    有修改的情况显然可以维护(1000000)个LCT,然后在修改边权后在LCT上link,cut(2^d)次。
    由于直接维护这么多个LCT不可承受,所以可以再次离线,枚举每个LCT,执行操作,再累加答案。
    然而问题并没有要求强制在线。
    这种有连通块的题,显然考虑并查集维护。
    考虑可撤销并查集。
    有一些边没有被修改过,显然先插入进去。
    注意到(Q)很小。
    每次修改时提取出在其他询问中被修改的边,插入它在当前位置的值,然后把当前位置的边插入到数据结构中。
    最后再撤销。
    最终时间复杂度(n2^d+2^d*Q^2*log_2n)

    #include<bits/stdc++.h>
    using namespace std;
    #define N 2000010
    #define M 2000010
    #define int long long
    int n,a[N],b[N],c[N],q,pr[M],f[N],sz[N],fc[N],vv[N],va[N],vg,vt[N],tp,k[N],x[N],cv[N],vp[N];
    int p[M],vi[M],ct,vu[M];
    int fd(int x){
    	while(f[x])
    		x=f[x];
    	return x; 
    }
    struct no{
    	int s,f,x,y;
    }ss[M];
    int mg(int x,int y){
    	x=fd(x);
    	y=fd(y);
    	if(x==y)
    		return 0;
    	if(sz[x]>sz[y])
    		swap(x,y);
    	int ans=sz[x]*sz[y];
    	ss[++tp]=((no){sz[y],f[x],x,y});
    	sz[y]+=sz[x];
    	f[x]=y;
    	return ans;
    }
    void rb(int x){
    	while(tp>x){
    		no z=ss[tp];
    		f[z.x]=z.f;
    		sz[z.y]=z.s;
    		tp--;
    	}
    }
    vector<int>vc[M];
    void si(){
    	vu[1]=1;
    	for(int i=2;i<M;i++){
    		if(!vi[i]){
    			p[++ct]=i;
    			vu[i]=-1;
    			pr[i]=i;
    		}
    		for(int j=1;i*p[j]<M;j++){
    			vi[i*p[j]]=1;
    			pr[i*p[j]]=p[j];
    			if(i%p[j]==0)
    				break;
    			vu[i*p[j]]=-vu[i];
    		}
    	}
    }
    void dfs(int v,int x,int y,int t){
    	if(y==ct+1){
    		if(!t)
    			vp[v]++;
    		cv[v]++;
    		if(t)
    			vc[v].push_back(x);
    		return;
    	}
    	dfs(v*fc[y],x,y+1,t);
    	dfs(v,x,y+1,t);
    }
    signed main(){
    	freopen("atoranta.in","r",stdin);
    	freopen("atoranta.out","w",stdout);
    	si();
    	memset(vi,0,sizeof(vi));
    	scanf("%lld",&n);
    	for(int i=1;i<n;i++)
    		scanf("%lld%lld%lld",&a[i],&b[i],&c[i]);
    	for(int i=1;i<=n;i++)
    		sz[i]=1;
    	for(int i=1;i<n;i++){
    		ct=0;
    		int x=c[i];
    		while(x!=1){
    			if(!vv[pr[x]])
    				fc[++ct]=pr[x];
    			vv[pr[x]]=1;
    			x/=pr[x];
    		}
    		dfs(1,i,1,1);
    		for(int j=1;j<=ct;j++)
    			vv[fc[j]]=0;
    	}
    	int ans=0;
    	for(int i=1;i<=n;i++)
    		sz[i]=1;
    	for(int i=1;i<M;i++)
    		if(vc[i].size()&&vu[i]){
    			for(int j=0;j<vc[i].size();j++)
    				ans+=vu[i]*mg(a[vc[i][j]],b[vc[i][j]]);
    			rb(0);
    		}
    	printf("%lld
    ",ans);
    	scanf("%lld",&q);
    	for(int i=1;i<=q;i++){
    		scanf("%lld%lld",&k[i],&x[i]);
    		ct=0;
    		int y=x[i];
    		while(y!=1){
    			if(!vv[pr[y]])
    				fc[++ct]=pr[y];
    			vv[pr[y]]=1;
    			y/=pr[y];
    		}
    		for(int j=1;j<=ct;j++)
    			vv[fc[j]]=0;
    		dfs(1,i,1,0);
    		vi[k[i]]=1;
    	}
    	for(int i=1;i<=n;i++)
    		if(vi[i]){
    			ct=0;
    			int y=c[i];
    			while(y!=1){
    				if(!vv[pr[y]])
    					fc[++ct]=pr[y];
    				vv[pr[y]]=1;
    				y/=pr[y];
    			}
    			for(int j=1;j<=ct;j++)
    				vv[fc[j]]=0;
    			dfs(1,i,1,0);
    		}
    	ans=0;
    	int ct=0,ok=0;
    	for(int i=1;i<M;i++){
    		if(cv[i]&&vu[i]){
    			ct+=q*q;
    			ans=0;
    			for(int j=0;j<vc[i].size();j++)
    				if(!vi[vc[i][j]])
    					ans+=vu[i]*mg(a[vc[i][j]],b[vc[i][j]]);
    			for(int j=1;j<=q;j++)
    				va[j]+=ans;
    			int tt=tp;
    			for(int j=1;j<=q;j++)
    				vt[k[j]]=c[k[j]];
    			if(vp[i]){
    				for(int j=1;j<=q;j++){
    					vt[k[j]]=x[j];
    					ans=0;
    					for(int l=1;l<=q;l++)
    						if(vt[k[l]]%i==0){
    							ok=1;
    							ans+=vu[i]*mg(a[k[l]],b[k[l]]);
    						}
    					rb(tt);
    					va[j]+=ans;
    				}
    			}
    			rb(0);
    		}
    	}
    	//printf("%d
    ",ok);
    	for(int i=1;i<=q;i++)
    		printf("%lld
    ",va[i]);
    }
    
  • 相关阅读:
    20200209 ZooKeeper 3. Zookeeper内部原理
    20200209 ZooKeeper 2. Zookeeper本地模式安装
    20200209 Zookeeper 1. Zookeeper入门
    20200206 尚硅谷Docker【归档】
    20200206 Docker 8. 本地镜像发布到阿里云
    20200206 Docker 7. Docker常用安装
    20200206 Docker 6. DockerFile解析
    20200206 Docker 5. Docker容器数据卷
    20200206 Docker 4. Docker 镜像
    Combining STDP and Reward-Modulated STDP in Deep Convolutional Spiking Neural Networks for Digit Recognition
  • 原文地址:https://www.cnblogs.com/ctmlpfs/p/14092130.html
Copyright © 2011-2022 走看看