50pts,五个点TLE求助,树剖
查看原帖
50pts,五个点TLE求助,树剖
214728
剑雪清寒楼主2022/7/8 21:07

有五个点TLE了。。。求助

#include <bits/stdc++.h>
inline long long read() {
	long long x,f;char ch;
	for(f=0;!isdigit(ch=getchar());f=ch=='-');
	for(x=ch-48;isdigit(ch=getchar());x=x*10+ch-48);
	return f?-x:x; 
}
inline void print(long long x,char las) {
	if(!x) {
		putchar(48),putchar(las);
		return ;
	}
	if(x<0) putchar('-'),x=-x;
	int ls[23],k=0;
	while(x) ls[++k]=x%10,x/=10;
	while(k) putchar(ls[k--]+48);
	putchar(las);
	return ;
}
struct road{
	int u,v;
}rrdd[100001];
int rd_sum=0;
struct edge {
	long long to,len;
	edge *next;
}rd[200000];
edge *head[100001];
struct node {
	long long value=0,wson=0,size=1,top=0,dfn=0,deep=0,dad=0;
}nd[100001];
struct tree {
	int cnt,pre[100001],ss=0;
	long long lson[400001],rson[400001],va[400001],lazy[400001];
	inline void update(int x) { va[x]=va[lson[x]] + va[rson[x]]; }
	inline void lz_ad(int x,int l,int r) {
		int mid=(l+r)>>1;
		va[lson[x]]+=lazy[x]*(mid-l+1);
		lazy[lson[x]]+=lazy[x];
		va[rson[x]]+=lazy[x]*(r-mid);
		lazy[rson[x]]+=lazy[x];
		lazy[x]=0;
		return ;
	}
	inline void build(int x,int l,int r) {
		ss++;
		if(l==r) {
			va[x]=pre[l];
			return ;
		}
		int mid=(l+r)>>1;
		lson[x]=ss+1;
		build(ss+1,l,mid);
		rson[x]=ss+1;
		build(ss+1,mid+1,r);
		update(x);
		return ;
	}
	inline void add(int x,int l,int r,int L,int R,long long ad_s) {
		if(l>R || r<L) return ;
		if(l>=L && r<=R) {
			va[x]+=(r-l+1)*ad_s;
			lazy[x]+=ad_s;
			return ;
		}
		int mid=(l+r)>>1;
		lz_ad(x,l,r);
		add(lson[x],l,mid,L,R,ad_s);
		add(rson[x],mid+1,r,L,R,ad_s);
		update(x);
		return ;
	}
	inline long long find(int x,int l,int r,int L,int R) {
		if(l>R || r<L) return 0;
		if(l==r) return va[x];
		int mid=(l+r)>>1;
		lz_ad(x,l,r);
		return find(lson[x],l,mid,L,R)+find(rson[x],mid+1,r,L,R); 
	}
}tr1;
inline void dfs1(int x,int dep) {
	nd[x].deep=dep;
	for(edge *i=head[x];i!=NULL;i=i->next) {
		int nex=i->to;
		if(nd[nex].deep) continue;
		nd[nex].dad=x;
		dfs1(nex,dep+1);
		nd[x].size+=nd[nex].size;
		if(nd[nex].size>nd[nd[x].wson].size) nd[x].wson=nex;
	}
	return ;
}
inline void dfs2(int x,int tp) {
	nd[x].dfn=++tr1.cnt,tr1.pre[tr1.cnt]=nd[x].value;nd[x].top=tp;
	if(nd[x].wson) dfs2(nd[x].wson,tp);
	for(edge *i=head[x];i!=NULL;i=i->next) {
		int nex=i->to;
		if(nd[nex].dfn) continue;
		dfs2(nex,nex);
	}
	return ;
}
int n=read(),m=read();
inline void query(int u,int v) {
	long long ans=0;
	while(nd[u].top!=nd[v].top) {
		if(nd[nd[u].top].deep<nd[nd[v].top].deep) std::swap(u,v);
		ans+=tr1.find(1,1,tr1.cnt,nd[nd[u].top].dfn,nd[u].dfn);
		u=nd[nd[u].top].dad;
	}
	if(nd[u].deep>nd[v].deep) std::swap(u,v);
	ans+=tr1.find(1,1,tr1.cnt,nd[u].dfn,nd[v].dfn);
	print(ans,'\n');
	return ;
}
int main() {
	for(int i=1;i<=n;i++) nd[i].value=read();
	for(int i=1;i<n;i++) {
		int u=read(),v=read();
		rrdd[i].u=u,rrdd[i].v=v;
		rd[rd_sum].to=v;rd[rd_sum].next=head[u];head[u]=&rd[rd_sum++];
		rd[rd_sum].to=u;rd[rd_sum].next=head[v];head[v]=&rd[rd_sum++];
	}
	dfs1(1,1);
	dfs2(1,1);
	tr1.build(1,1,tr1.cnt);
	while(m--) {
		int job=read(),a=read(),b;
		switch (job) {
			case 1:
				b=read();
				tr1.add(1,1,tr1.cnt,nd[a].dfn,nd[a].dfn,b);
				break;
			case 2:
				b=read();
				tr1.add(1,1,tr1.cnt,nd[a].dfn,nd[a].dfn+nd[a].size-1,b);
				break;
			case 3:
				query(1,a);
		}
	}
	return 0;
}

2022/7/8 21:07
加载中...