• cf757g暂存


    不知道哪里写挂了,一直过不去
    但是正确性是有保证的。

    #include<bits/stdc++.h>
    using namespace std;
    #define N 200010
    #define ll long long
    int h[N],v[N*2],w[N*2],nxt[N*2],ec,n,q,f[N],tp[N],p[N],sz[N],pp[N],id[N],ct,lc[N*100],rc[N*100],st[N],rt[N],cg,vv[N];
    ll s[N*150],cc[N*150],sd[N],sp[N],d[N];
    void add(int x,int y,int z){v[++ec]=y;w[ec]=z;nxt[ec]=h[x];h[x]=ec;}
    void d1(int x,int fa){
    	sz[x]=1;
    	f[x]=fa;
    	for(int i=h[x];i;i=nxt[i])
    		if(v[i]!=fa){
    			d[v[i]]=w[i]+d[x];
    			vv[v[i]]=w[i];
    			d1(v[i],x);
    			sz[x]+=sz[v[i]];
    			if(sz[p[x]]<sz[v[i]])
    				p[x]=v[i];
    		}
    }
    void d2(int x,int fa,int t){
    	tp[x]=t;
    	id[x]=++ct;
    	st[ct]=x;
    	if(p[x])
    		d2(p[x],x,t);
    	for(int i=h[x];i;i=nxt[i])
    		if(v[i]!=fa&&v[i]!=p[x])
    			d2(v[i],x,v[i]);
    }
    void add(int &o,int l,int r,int x,int y){
    	if(r<x||y<l)return;
    	++cg;
    	lc[cg]=lc[o];
    	rc[cg]=rc[o];
    	cc[cg]=cc[o];
    	s[cg]=s[o];
    	o=cg;
    	if(x<=l&&r<=y){
    		cc[o]++;
    		s[o]+=sp[r]-sp[l-1];
    		return;
    	}
    	int md=(l+r)/2;
    	add(lc[o],l,md,x,y);
    	add(rc[o],md+1,r,x,y);
    	s[o]=s[lc[o]]+s[rc[o]]+cc[o]*(sp[r]-sp[l-1]);
    }
    ll qq(int o,int l,int r,int x,int y,ll z){
    	if(r<x||y<l)return 0;
    	if(!o)return (sp[min(r,y)]-sp[max(l,x)-1])*z;
    	if(x<=l&&r<=y)return z*(sp[r]-sp[l-1])+s[o];
    	int md=(l+r)/2;
    	return qq(lc[o],l,md,x,y,z+cc[o])+qq(rc[o],md+1,r,x,y,z+cc[o]);
    }
    void bd(int &o,int l,int r){
    	o=++cg;
    	if(l==r)return;
    	int md=(l+r)/2;
    	bd(lc[o],l,md);
    	bd(rc[o],md+1,r);
    }
    void ad(int x,int y){
    	while(y){
    		add(rt[x],1,n,id[tp[y]],id[y]);
    		y=f[tp[y]];
    	}
    }
    ll qu(int x,int va){
    	ll ans=0,y=va;
    	while(y){
    		ans+=qq(rt[x],1,n,id[tp[y]],id[y],0);
    		y=f[tp[y]];
    	}
    	return x*d[va]+sd[x]-2*ans;
    }
    int main(){
    	scanf("%d%d",&n,&q);
    	for(int i=1;i<=n;i++)
    		scanf("%d",&pp[i]);
    	for(int i=1;i<n;i++){
    		int x,y,z;
    		scanf("%d%d%d",&x,&y,&z);
    		add(x,y,z);
    		add(y,x,z);
    	}
    	d1(1,0);
    	d2(1,0,1);
    	for(int i=1;i<=n;i++){
    		sd[i]=sd[i-1]+d[pp[i]];
    		sp[i]=sp[i-1]+vv[st[i]];
    	}
    	bd(rt[0],1,n);
    	for(int i=1;i<=n;i++){
    		rt[i]=rt[i-1];
    		ad(i,pp[i]);
    	}
    	ll la=0;
    	for(int i=1;i<=q;i++){
    		int op,l,r,x;
    		scanf("%d",&op);
    		if(op==1){
    			scanf("%d%d%d",&l,&r,&x);
    			la%=(1<<30);
    			x^=la;
    			l^=la;
    			r^=la;
    			la=qu(r,x)-qu(l-1,x);
    			printf("%lld
    ",la);
    		}
    		else{
    			scanf("%d",&x);
    			la%=(1<<30);
    			x^=la;
    			swap(pp[x],pp[x+1]);
    			sd[x]=sd[x-1]+d[pp[x]];
    			rt[x]=rt[x-1];
    			if(cg<=29000000)ad(x,pp[x]);
    			else{
    				for(int j=1;j<=cg;j++)
    					lc[j]=rc[j]=s[j]=cc[j]=0;
    				cg=0;
    				for(int j=1;j<=n;j++){
    					rt[j]=rt[j-1];
    					ad(j,pp[j]);
    				}
    			}
    		}
    	}
    }
    
  • 相关阅读:
    XML
    编码格式
    CSS 实现加载动画之七-彩环旋转
    CSS 实现加载动画之六-大风车
    CSS 实现加载动画之五-光盘旋转
    CSS 实现加载动画之四-圆点旋转
    CSS 实现加载动画之三-钢琴按键
    CSS 实现加载动画之二-圆环旋转
    CSS 实现加载动画之一-菊花旋转
    JS案例之8——从一个数组中随机取数
  • 原文地址:https://www.cnblogs.com/ctmlpfs/p/13673572.html
Copyright © 2020-2023  润新知