树链剖分,线段树全MLE求调
查看原帖
树链剖分,线段树全MLE求调
584977
Susking楼主2022/7/23 20:04

rt,差不多MLE一页了……qwq每次内存都是125MB……

#include<bits/stdc++.h>
#define ll long long
#define MN 100020
#define zuo x<<1
#define mid (l+r)>>1
#define you (x<<1)+1
using namespace std;
int N,M,RR ,op,x,y,z,L,R , head[MN];
ll P ,W [MN], ans;
int deep[MN],siz[MN],son[MN],fa[MN],top[MN];
int tim[MN],t;
ll sum[5*MN],lazy[5*MN];
struct edge{
	int to,nxt;
}e[MN*2];

void build(int l,int r,int x){
	if(l==r){sum[x]=tim[l]%P ;return ;}
	build(l,mid,zuo); build(mid+1,r,you);
	sum[x]=(sum[zuo]+sum[you])%P ;
}
void pushdown(int l,int r,int x){
	if(lazy[x]){
		sum[zuo]+=(mid-l+1)%P *lazy[x]%P ; sum[you]+=(r-mid)%P *lazy[x]%P ;
		lazy[zuo]+=lazy[x]%P ; lazy[you]+=lazy[x%P ];
		lazy[x]=0;
	}
}
void add(int l,int r,int x){
	if(L<=l &&r<=R){
		sum[x]+=(r-l+1)*z%P ;
		lazy[x]+=z%P ;
		return ;
	}
	if(lazy[x]) pushdown(l,r,x);
	if(mid>=L) add(l,mid,zuo);
	if(R>mid)add(mid+1,r,you);
	sum[x]=(sum[zuo]+sum[you])%P ;
}
void query(int l,int r,int x){
	if(L<=l &&r<=R){ans=(ans+sum[x])%P ;return ;}
	if(lazy[x]) pushdown(l,r,x);
	if(mid>=L) query(l,mid,zuo);
	if(R>mid) query(mid+1,r,you);
}
void dfs1(int x,int dep){
	int ms=0; deep[x]=dep;siz[x]=1;
	for(int i=head[x],v;i!=1;i=e[i].nxt){
		v=e[i].to;
		if(v==fa[x]) continue;
		fa[v]=x; dfs1(v,dep+1);
		siz[x]+=siz[v];
		if(ms<siz[v]) son[x]=v,ms=siz[v];
	}
}
void dfs2(int x,int tp){
	top[x]=tp;tim[++t]=x;
	if(!son[x]) return ;
	dfs2(son[x],tp);
	for(int i=head[x],v;i!=1;i=e[i].nxt){
		v=e[i].to;
		if(v==fa[x] ||v==son[x]) continue;
		dfs2(v,v);
	}
}
void wayadd(){
	while(top[x]!=top[y]){
		if(deep[top[x]]<deep[top[y]]) swap(x,y);
		L=tim[top[x]];R=tim[x];
		add(1,N,1);
		x=fa[top[x]];
	}
	if(deep[x]<deep[y]) swap(x,y);
	L=tim[y];R=tim[x];
	add(1,N ,1);
}
void waysum(){
	ll ans=0;
	while(top[x]!=top[y]){
		if(deep[top[x]]<deep[top[y]]) swap(x,y);
		L=tim[top[x]];R=tim[x];
		query(1,N,1);
		x=fa[top[x]];
	}
	if(deep[x]<deep[y]) swap(x,y);
	L=tim[y];R=tim[x];
	query(1,N ,1);
	printf("%lld",ans%P );
}
int main(){
	memset(head,-1,sizeof(head));
	scanf("%d%d%d%lld",&N ,&M ,&RR ,&P); ++M ;
	for(ll i=1;i<=N;++i) scanf("%lld",&W[i]);
	for(ll i=0,xx,yy;i<(N-1)<<1;i+=2){
		scanf("%lld%lld",&xx,&yy);
		e[i].to=yy;e[i].nxt=head[xx];head[xx]=i;
		e[i^1].to=xx;e[i^1].nxt=head[yy];head[yy]=i^1;
	}
	dfs1(RR,1); dfs2(RR,RR); build(1,N,1);
	while(--M){
		scanf("%d%d",&op,&x);
		switch(op){
			case 1:scanf("%d%d",&y,&z),wayadd();break;
			case 2:scanf("%d",&y),waysum();break;
			case 3:scanf("%d",&z),L=tim[x],R=tim[x]+siz[x]-1,add(1,N,1);break;
			case 4:L=tim[x],R=tim[x]+siz[x]-1,query(1,N,1),printf("%lld\n",ans);break;
		}
	}
}
2022/7/23 20:04
加载中...