再求马蜂锐评
  • 板块灌水区
  • 楼主F1NE
  • 当前回复4
  • 已保存回复4
  • 发布时间2024/10/23 17:02
  • 上次更新2024/10/23 19:05:19
查看原帖
再求马蜂锐评
1163927
F1NE楼主2024/10/23 17:02

rt,写的是树链剖分,求观感

#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
const int maxi=1e5+9; 
struct node{
	vector<int> e;
	int d,siz,son,f,top,v,id;
}trr[maxi];
struct segment_tree{
	ll sum,laz;
	int s,t,m;
}sgt[maxi<<2];
ll P;
int N,M,rt,L,R,D,cnt,a[maxi]; 
#define now trr[p] 
#define mxsn trr[trr[p].son]
#define to trr[i]
void dfs1(int p){
	now.siz=1;
	for(int i:now.e){
		if(i!=now.f){
			to.f=p,to.d=now.d+1;
			dfs1(i);
			now.siz+=to.siz;
			if(mxsn.siz<to.siz){
				now.son=i;
			}
		}
	}
	return;
}
void dfs2(int p){
	cnt++;
//cerr<<"p="<<p
//	<<",cnt="<<cnt
//	<<'\n'; 
	now.id=cnt;
	a[cnt]=now.v;
	if(now.siz==1)return;
	mxsn.top=now.top;
	dfs2(now.son);
	for(int i:now.e){
		if(i==now.f||i==now.son)continue;
		to.top=i;
		dfs2(i);
	}
	
	return;
}
#define _ls p<<1
#define _rs p<<1|1
#define now sgt[p]
#define ls sgt[_ls]
#define rs sgt[_rs]
inline ll mod(ll a){return a%P;}
inline void update(int p){
	now.sum=mod(ls.sum+rs.sum);
}
inline void pushdown(int p){
	if(now.laz){
		ls.sum=mod(ls.sum+now.laz*(ls.t-ls.s+1));
		rs.sum=mod(rs.sum+now.laz*(rs.t-rs.s+1));
		ls.laz=mod(ls.laz+now.laz);
		rs.laz=mod(rs.laz+now.laz);
		now.laz=0;
	}
	return;
}
//inline void look(int p){
//cerr<<"p="<<p
//	<<",s="<<now.s
//	<<",t="<<now.t
//	<<",sum="<<now.sum
//	<<'\n';
//}
//void test(int p){
//	look(p);
//	if(now.s==now.t)return;
//	pushdown(p);
//	test(_ls),test(_rs);
//	update(p);
//	return;
//}
void build(int s,int t,int p){
	now.s=s,now.t=t,now.m=(s+t)>>1;
	if(s==t){
		now.sum=1ll*a[s]%P;
//look(p);
		return;
	}
	build(s,now.m,_ls),build(now.m+1,t,_rs);
	update(p);
//look(p);
	return;
}
void wt(int p){
	if(L<=now.s&&now.t<=R){
		now.sum+=1ll*D*(now.t-now.s+1)%P;
		now.laz=mod(now.laz+1ll*D);
		return;
	}
	pushdown(p);
	if(L<=now.m)wt(_ls);
	if(now.m<R)wt(_rs);
	update(p);
	return;
}
ll rd(int p){
	if(L<=now.s&&now.t<=R)return now.sum;
	ll ans=0;
	pushdown(p);
	if(L<=now.m)ans=mod(ans+rd(_ls));
	if(now.m<R)ans=mod(ans+rd(_rs));
	update(p);
	return ans;
}
#define nowx trr[x]
#define nowy trr[y]
#define topx trr[nowx.top]
#define topy trr[nowy.top]
inline void _1(int x,int y,int z){
	D=z;
	if(nowx.top!=nowy.top){
		for(;nowx.top!=nowy.top;){
			if(topx.d>topy.d)swap(x,y);
			L=topy.id,R=nowy.id;wt(1);
			y=topy.f;
		}
	}
	if(nowx.d>nowy.d)swap(x,y);
	L=nowx.id,R=nowy.id;wt(1);
	return;
}
inline ll _2(int x,int y){
	ll ans=0;
	if(trr[x].top!=trr[y].top){
		for(;nowx.top!=nowy.top;){
			if(topx.d>topy.d)swap(x,y);
			L=topy.id,R=nowy.id;
			ans=mod(ans+rd(1));
			y=topy.f; 
		}
	}
	if(nowx.d>nowy.d)swap(x,y);
	L=nowx.id,R=nowy.id;ans=mod(ans+rd(1));
	return ans;
}
inline void _3(int x,int z){
//cerr<<"x="<<x<<",z="<<z<<'\n';
	L=nowx.id,R=L+nowx.siz-1,D=z;
//cerr<<"L="<<L
//	<<",R="<<R
//	<<",D="<<D
//	<<",id="<<nowx.id
//	<<'\n';
	wt(1); 
	return;
}
inline ll _4(int x){
	L=nowx.id,R=L+nowx.siz-1;
	return mod(rd(1));
}
int main(){
	cin>>N>>M>>rt>>P;
	for(int i=1;i<=N;i++)scanf("%d",&trr[i].v);
	for(int i=1,u,v;i<N;i++){
		scanf("%d%d",&u,&v);
		trr[u].e.push_back(v);
		trr[v].e.push_back(u); 
	}
	trr[rt].d=1,trr[rt].top=rt;
	dfs1(rt);
	dfs2(rt);
//for(int i=1;i<=N;i++)cerr<<to.id<<' ';cerr<<'\n';
	build(1,N,1);
//test(1);
	for(int i=1,op,x,y,z;i<=M;i++){
		scanf("%d%d",&op,&x);
		if(op==1){
			scanf("%d%d",&y,&z);
			_1(x,y,z);
		}
		if(op==2){
			scanf("%d",&y);
			printf("%lld\n",_2(x,y));
		}
		if(op==3){

			scanf("%d",&z);
//cerr<<"x="<<x<<",z="<<z<<'\n';
			_3(x,z); 
		}
		if(op==4)printf("%lld\n",_4(x));
	}
	return 0;
} 
2024/10/23 17:02
加载中...