萌新刚学OI 3秒 求助:分块+树剖 88pts WA最后1个点 QwQ
查看原帖
萌新刚学OI 3秒 求助:分块+树剖 88pts WA最后1个点 QwQ
261046
Cht_master楼主2021/3/22 17:48

自闭了不知道有什么问题(哪位大佬知道最后1个点Hack的原理是什么呀啊啊啊QwQ)QAQ

#include<bits/stdc++.h>
#define ll long long
#define inl inline
#define rg register
using namespace std;
const int maxN(2e5),maxSqrtN(448);
const ll inf(13e10);
int n,q;ll tw[maxN+5];
void read_int(int &x){
	x=0;int fg(1);char t(getchar());
	while(t<'0'||t>'9'){if(t=='-')fg=-1;t=getchar();}
	while(t>='0'&&t<='9')x=(x<<1)+(x<<3)+(t^48),t=getchar();
	x*=fg;
}
void read_ll(ll &x){
	x=0;ll fg(1);char t(getchar());
	while(t<'0'||t>'9'){if(t=='-')fg=-1;t=getchar();}
	while(t>='0'&&t<='9')x=(x<<1)+(x<<3)+(t^48),t=getchar();
	x*=fg;
}
void print_ll(ll x){
	if(x<0)putchar('-'),x=-x;
	if(x>9)print_ll(x/10);
	putchar(x%10+'0');
}
int cnt;struct Edge{int u,v;}edge[maxN+5];//单项边用于处理操作1.
struct Chunking{
	int len,grp[maxN+5],cl[maxSqrtN+5],cr[maxSqrtN+5];
	bool neg[maxSqrtN+5];ll val[maxN+5],sum[maxSqrtN+5],minn[maxSqrtN+5],maxn[maxSqrtN+5];
	inl void init(){
		len=sqrt(n);
		for(rg int i(1);i<=n;++i)grp[i]=(i-1)/len+1,val[i]=tw[i],sum[grp[i]]+=tw[i];
		for(rg int i(1);i<=grp[n]-1;++i)neg[i]=0,cl[i]=(i-1)*len+1,cr[i]=i*len;
		cl[grp[n]]=(grp[n]-1)*len+1,cr[grp[n]]=n;
		for(int i(1);i<=grp[n];++i)minn[i]=inf,maxn[i]=-inf;
		for(rg int i(1);i<=n;++i)minn[grp[i]]=min(minn[grp[i]],tw[i]),maxn[grp[i]]=max(maxn[grp[i]],tw[i]);
	}
	inl void reset(int sec){
		for(rg int i(cl[sec]);i<=cr[sec];++i)if(neg[sec])val[i]=-val[i];
		neg[sec]=0,sum[sec]=0,minn[sec]=inf,maxn[sec]=-inf;
		for(rg int i(cl[sec]);i<=cr[sec];++i)sum[sec]+=val[i],minn[sec]=min(minn[sec],val[i]),maxn[sec]=max(maxn[sec],val[i]);
	}
	inl void updp(int u,ll w){reset(grp[u]),val[u]=w,reset(grp[u]);}
	inl void pos_neg(int l,int r){
		reset(grp[l]);
		for(rg int i(l);i<=min(cr[grp[l]],r);++i)
			sum[grp[l]]-=val[i]*2,val[i]=-val[i],
			minn[grp[l]]=min(minn[grp[l]],val[i]),maxn[grp[l]]=max(maxn[grp[l]],val[i]);
		for(rg int i(grp[l]+1);i<=grp[r]-1;++i)if(!neg[i])neg[i]=1;else neg[i]=0;
		if(grp[l]!=grp[r]){
			reset(grp[r]);
			for(rg int i(cl[grp[r]]);i<=r;++i)
				sum[grp[r]]-=val[i]*2,val[i]=-val[i],
				minn[grp[r]]=min(minn[grp[r]],val[i]),maxn[grp[r]]=max(maxn[grp[r]],val[i]);
		}
	}
	inl ll query_sum(int l,int r){
		ll ans(0);
		reset(grp[l]);
		for(rg int i(l);i<=min(cr[grp[l]],r);++i)ans+=val[i];
		for(rg int i(grp[l]+1);i<=grp[r]-1;++i)if(neg[i])ans+=-sum[i];else ans+=sum[i];
		if(grp[l]!=grp[r]){
			reset(grp[r]);
			for(rg int i(cl[grp[r]]);i<=r;++i)ans+=val[i];
		}
		return ans;
	}
	inl ll query_min(int l,int r){
		ll ans(inf);
		reset(grp[l]);
		for(rg int i(l);i<=min(cr[grp[l]],r);++i)ans=min(ans,val[i]);
		for(rg int i(grp[l]+1);i<=grp[r]-1;++i)if(neg[i])ans=min(ans,-maxn[i]);else ans=min(ans,minn[i]);
		if(grp[l]!=grp[r]){
			reset(grp[r]);
			for(rg int i(cl[grp[r]]);i<=r;++i)ans=min(ans,val[i]);
		}
		return ans;
	}
	inl ll query_max(int l,int r){
		ll ans(-inf);
		reset(grp[l]);
		for(rg int i(l);i<=min(cr[grp[l]],r);++i)ans=max(ans,val[i]);
		for(rg int i(grp[l]+1);i<=grp[r]-1;++i)if(neg[i])ans=max(ans,-minn[i]);else ans=max(ans,maxn[i]);
		if(grp[l]!=grp[r]){
			reset(grp[r]);
			for(rg int i(cl[grp[r]]);i<=r;++i)ans=max(ans,val[i]);
		}
		return ans;
	}
}chnk;
struct Cut_Tree{
	ll val[maxN+5];
	int fa[maxN+5],dep[maxN+5],siz[maxN+5],wson[maxN+5],top[maxN+5],seg[maxN+5],lf[maxN+5],cnt;
	int out[maxN+5],vis[maxN+5];vector<int>node[maxN+5];vector<ll>dist[maxN+5];
	inl void add(int u,int v,ll w){
		if(!out[u])node[u].push_back(0),dist[u].push_back(0);
		++out[u],node[u].push_back(v),dist[u].push_back(w);
	}
	inl void dfs1(int u,int pre){
		vis[u]=1,fa[u]=pre,dep[u]=dep[pre]+1,siz[u]=1;int maxson(-1);
		if(out[u]==1&&vis[node[u][1]])lf[u]=1;
		for(rg int i(1);i<=out[u];++i){
			int v(node[u][i]);ll w(dist[u][i]);if(vis[v])continue;
			val[v]=w,dfs1(v,u),siz[u]+=siz[v];
			if(siz[v]>maxson)maxson=siz[v],wson[u]=v;
		}
	}
	inl void dfs2(int u,int topf){
		vis[u]=1,seg[u]=++cnt,tw[cnt]=val[u],top[u]=topf;
		if(lf[u])return;dfs2(wson[u],topf);
		for(rg int i(1);i<=out[u];++i){int v(node[u][i]);if(vis[v])continue;dfs2(v,v);}
	}
	inl int LCA(int u,int v){
		while(top[u]!=top[v]){if(dep[top[u]]<dep[top[v]])swap(u,v);u=fa[top[u]];}
		if(dep[u]>dep[v])return v;return u;
	}
	inl void Prechain(int u,int v,int &type,int &s1,int &e1,int &s2,int &e2){
		int lca(LCA(u,v));
		if(lca==u||lca==v){
			type=1;
			if(lca==v)swap(u,v);
			for(rg int i(1);i<=out[u];++i){
				int tv(node[u][i]);if(tv==fa[u])continue;
				if(LCA(tv,v)==tv){s1=tv,e1=v;return;}
			}
		}else{
			type=2;
			for(rg int i(1);i<=out[lca];++i){
				int tv(node[lca][i]);if(tv==fa[lca])continue;
				if(LCA(tv,u)==tv)s1=tv,e1=u;
				if(LCA(tv,v)==tv)s2=tv,e2=v;
			}
		}
	}
	inl void updp(int u,ll w){chnk.updp(seg[u],w);}//修改点权.
	inl void updchain(int u,int v){//将链修改为相反数.
		while(top[u]!=top[v]){
			if(dep[top[u]]<dep[top[v]])swap(u,v);
			chnk.pos_neg(seg[top[u]],seg[u]),u=fa[top[u]];
		}
		if(dep[u]>dep[v])swap(u,v);chnk.pos_neg(seg[u],seg[v]);
	}
	inl ll qrychain(int u,int v,int type){
		ll ans;
		if(!type)ans=0;if(type==-1)ans=inf;if(type==1)ans=-inf;
		while(top[u]!=top[v]){
			if(dep[top[u]]<dep[top[v]])swap(u,v);
			if(!type)ans+=chnk.query_sum(seg[top[u]],seg[u]);//边权和.
			if(type==-1)ans=min(ans,chnk.query_min(seg[top[u]],seg[u]));//最小值.
			if(type==1)ans=max(ans,chnk.query_max(seg[top[u]],seg[u]));//最大值.
			u=fa[top[u]];
		}
		if(dep[u]>dep[v])swap(u,v);
		if(!type)ans+=chnk.query_sum(seg[u],seg[v]);
		if(type==-1)ans=min(ans,chnk.query_min(seg[u],seg[v]));
		if(type==1)ans=max(ans,chnk.query_max(seg[u],seg[v]));
		return ans;
	}
}cttr;
int main(){
	read_int(n);int u,v,mrk;ll w;
	for(rg int i(1);i<=n-1;++i)
		read_int(u),read_int(v),read_ll(w),
		cttr.add(u+1,v+1,w),cttr.add(v+1,u+1,w),
		edge[++cnt].u=u+1,edge[cnt].v=v+1;
	cttr.dfs1(1,0),memset(cttr.vis,0,sizeof(cttr.vis)),cttr.dfs2(1,1),chnk.init();
	read_int(q);
	for(rg int i(1);i<=q;++i){
		string op;cin>>op;
		int type,s1,e1,s2,e2;
		if(op=="C"){
			read_int(mrk),read_ll(w);
			if(cttr.dep[edge[mrk].u]>cttr.dep[edge[mrk].v])cttr.updp(edge[mrk].u,w);
			else cttr.updp(edge[mrk].v,w);//修改层数较深的那个点.
		}
		if(op=="N"){
			read_int(u),read_int(v),cttr.Prechain(u+1,v+1,type,s1,e1,s2,e2);
			cttr.updchain(s1,e1);if(type==2)cttr.updchain(s2,e2);
		}
		if(op=="SUM"){
			read_int(u),read_int(v),cttr.Prechain(u+1,v+1,type,s1,e1,s2,e2);
			ll ans(cttr.qrychain(s1,e1,0));
			if(type==2)ans+=cttr.qrychain(s2,e2,0);
			print_ll(ans),puts("");
		}
		if(op=="MAX"){
			read_int(u),read_int(v),cttr.Prechain(u+1,v+1,type,s1,e1,s2,e2);
			ll ans(cttr.qrychain(s1,e1,1));
			if(type==2)ans=max(ans,cttr.qrychain(s2,e2,1));
			print_ll(ans),puts("");
		}
		if(op=="MIN"){
			read_int(u),read_int(v),cttr.Prechain(u+1,v+1,type,s1,e1,s2,e2);
			ll ans(cttr.qrychain(s1,e1,-1));
			if(type==2)ans=min(ans,cttr.qrychain(s2,e2,-1));
			print_ll(ans),puts("");
		}
	}
	return 0;
}
2021/3/22 17:48
加载中...