树链加线段树 但是TLE求调QAQ
查看原帖
树链加线段树 但是TLE求调QAQ
1067741
Andyxz楼主2024/12/24 18:20
#include<bits/stdc++.h>
#define ll int
#define MAXN 200001
using namespace std;
ll n,m,a[MAXN],tag[MAXN<<2];
int nxt[MAXN],head[MAXN],to[MAXN];
ll top[MAXN],fa[MAXN],deep[MAXN],siz[MAXN],id[MAXN],zh[MAXN],c[MAXN];
ll dot1;
ll cnt;
ll cntt=-1;
ll dd;
struct st{
	ll x=0;
	ll m=0;
	ll l=0;
	ll r=0;
}ans[MAXN<<2];
//vector<st> q,qq;
//vector<ll> qr;
ll dot;
ll s;
ll ma;
bool bq;
inline void add(int u,int v){
	nxt[++cntt]=head[u];
	head[u]=cntt;
	to[cntt]=v;
	swap(u,v);
	nxt[++cntt]=head[u];
	head[u]=cntt;
	to[cntt]=v;
	return;
}
inline ll ls(ll x){
	return x<<1;
}
inline ll rs(ll y){
	return y<<1|1;
}
/*inline void f(ll p,ll l,ll r,ll k){
	tag[p]=tag[p]+k;
	ans[p]=ans[p]+k*(r-l+1);
}*/
st merge(st x,st y) {
    st an;
    an.x=x.x+y.x;
    an.l=max(x.l,x.x+y.l);
    an.r=max(y.r,y.x+x.r);
    an.m=max(max(x.m,y.m),x.r+y.l);
    return an;
}
void in(){
	cin>>n;
	for(register int i=1;i<=n;i++)
	scanf("%d",&c[i]);
	int x,y;
	for(register int i=1;i<=n-1;i++){
		scanf("%d%d",&x,&y);
		add(x,y);
	}
	cin>>m;
	return;
}
inline void push_up(ll p){
	ans[p].x=ans[rs(p)].x+ans[ls(p)].x;
	ans[p].m=max(max(ans[rs(p)].l+ans[ls(p)].r,ans[p].x),max(ans[rs(p)].m,ans[ls(p)].m));
	ans[p].l=max(ans[ls(p)].x+ans[rs(p)].l,ans[ls(p)].l);
	ans[p].r=max(ans[rs(p)].x+ans[ls(p)].r,ans[rs(p)].r);
	return;
}
inline void push_down(ll p,ll l,ll r){
	ll mid=(l+r)>>1;
	ll k=tag[p];
	int rr=rs(p),lr=ls(p);
	ans[rr].x=k*(r-mid);
	ans[rr].m=ans[rr].r=ans[rr].l=max(0,ans[rr].x);
	tag[rr]=k;
	ans[lr].x=k*(mid-l+1);
	ans[lr].m=ans[lr].l=ans[lr].r=max(0,ans[lr].x);
	tag[lr]=k;
	tag[p]=0;
	return;
}
void build(ll p,ll l,ll r){
	tag[p]=0;
	if(l==r){
		ans[p].x=a[l]*(r-l+1);
	ans[p].m=ans[p].r=ans[p].l=max(0,ans[p].x);
	tag[p]=a[l];
		//cout<<l<<" "<<a[l]<<endl;
		return;
	}
	ll mid=(l+r)>>1;
	build(ls(p),l,mid);
	build(rs(p),mid+1,r);
	ans[p]=merge(ans[ls(p)],ans[rs(p)]);
	return; 
}
inline void update(ll l1,ll r1,ll l,ll r,ll p,ll k){
	if(l1<=l&&r<=r1){
	ans[p].x=k*(r-l+1);
	ans[p].m=ans[p].r=ans[p].l=max(0,ans[p].x);
	tag[p]=k;
	//cout<<l<<" "<<r<<endl;
		return;
	}
	if(tag[p]) push_down(p,l,r);
	ll mid=(l+r)>>1;
	if(l1<=mid) update(l1,r1,l,mid,ls(p),k);
	if(r1>mid) update(l1,r1,mid+1,r,rs(p),k);
	ans[p]=merge(ans[ls(p)],ans[rs(p)]);
	return;
}
inline st query(ll x,ll y,ll l,ll r,ll p){
	if(x<=l&&y>=r){
		//cout<<ans[p].x<<" "<<x<<" "<<y<<endl;
		return ans[p];
	}
	st L,R;
	ll mid=(l+r)>>1;
	if(tag[p]) push_down(p,l,r);
	if(x<=mid) L=query(x,y,l,mid,ls(p));
	if(y>mid) R=query(x,y,mid+1,r,rs(p));
	return merge(L,R);
}
inline void dfs1(int f,int p,int d){
	deep[p]=d;
	fa[p]=f;
	siz[p]=1;int maz=-1;
	for(register int i=head[p];~i;i=nxt[i]){
		if(to[i]==f) continue;
		else{
			dfs1(p,to[i],d+1);
			if(siz[to[i]]>maz) zh[p]=to[i];
			siz[p]+=siz[to[i]];
		}
	}
	return;
}
inline void dfs2(int too,int p){
	top[p]=too;
	id[p]=++cnt;
	a[id[p]]=c[p];
	if(siz[p]>1) dfs2(too,zh[p]);
	else return;
	for(register int i=head[p];~i;i=nxt[i]){
		if(to[i]==fa[p]||to[i]==zh[p]) continue;
		else{
			dfs2(to[i],to[i]);
		}
	}
	return;
}
inline void upd1(int x,int y,int k){
	while(top[x]!=top[y]){
		if(deep[top[x]]<deep[top[y]]) swap(x,y);
		update(id[top[x]],id[x],1,n,1,k);
		x=fa[top[x]];
	}
	if(deep[x]>deep[y]) swap(x,y);
	update(id[x],id[y],1,n,1,k);
	return;
}
st que1(int u,int v) {
    st L,R;
    for(int fu=top[u],fv=top[v];fu^fv;) {
        if(deep[fu]<deep[fv]) {
            R=merge(query(id[fv],id[v],1,n,1),R);
            v=fa[fv],fv=top[v];
        } else {
            L=merge(query(id[fu],id[u],1,n,1),L);
            u=fa[fu],fu=top[u];
        }
    }
    if(deep[u]>deep[v]) {
        L=merge(query(id[v],id[u],1,n,1),L);
    } else {
        R=merge(query(id[u],id[v],1,n,1),R);
    }
	swap(L.l,L.r);
    return merge(L,R);
}
int main(){
	int a1,b1,c1,d1,e1,f1;
	memset(to,-1,sizeof to);
	memset(head,-1,sizeof head);
	memset(nxt,-1,sizeof nxt);
	in();
	dfs1(1,1,1);
	dfs2(1,1);
	//for(int i=1;i<=n;i++)	cout<<zh[i]<<" ";
	//cout<<endl;
	build(1,1,n);
	//cout<<111<<endl;
	while(m--){
		scanf("%d",&a1);
		if(a1==1){
				scanf("%d%d",&b1,&d1);
				printf("%d\n",que1(b1,d1).m);
			}
		else{
				scanf("%d%d%d",&e1,&f1,&c1);
				upd1(e1,f1,c1);	
			}
		}
	return 0;
}

树链加线段树 但是tle了 球调((

2024/12/24 18:20
加载中...