RE 求调
查看原帖
RE 求调
581316
small_john楼主2024/8/4 15:57
#include <bits/stdc++.h>
using namespace std;
const int N = 4e4+5;
int n,m1,m2,dfn[N],son[N],dep[N],f[N],top[N],idx,sz[N];
vector<int> g[N];
void dfs1(int u,int fa)
{
	dfn[u] = ++idx,sz[u] = 1,dep[u] = dep[fa]+1,f[u] = fa;
	for(auto v:g[u])
	{
		if(v==fa) continue;
		dfs1(v,u);
		sz[u]+=sz[v];
		if(sz[v]>sz[son[u]]) son[u] = v;
	}
}
void dfs2(int u,int tp)
{
	top[u] = tp;
	if(!son[u]) return;
	dfs2(son[u],tp);
	for(auto v:g[u])
	{
		if(v==son[u]||v==f[u]) continue;
		dfs2(v,v);
	}
}
inline int jump(int x,int y)//x->y
{
	while(top[x]!=top[y])
	{
		if(f[top[x]]==y) return top[x];
		x = f[top[x]];
	}
	return son[y];
}
struct node{
	int t,op,l,r,k;
}q[N*5],ql[N*5],qr[N*5];
int t[N];
#define lowbit(x) (x&(-x))
inline void add(int x,int y)
{
	for(;x<=n;x+=lowbit(x))
		t[x]+=y;
}
inline int ask(int x)
{
	int res = 0;
	for(;x;x-=lowbit(x))
		res+=t[x];
	return res;
}
inline int change(int l,int r,int v){add(l,v),add(r+1,-v);}
int cnt,cnt1,cnt2,ans[N];
void solve(long long l,long long r,int x,int y)
{
	if(l==r)
	{
		for(int i = x;i<=y;i++)
			if(q[i].op==2) ans[q[i].t] = l;
		return;
	}
	int mid = (l+r)/2;
	int cntl = 0,cntr = 0,tmp;
	for(int i = x;i<=y;i++)
	{
		if(q[i].op==0)
		{
			if(q[i].k<=mid) ql[++cntl] = q[i],change(q[i].l,q[i].r,1);
			else qr[++cntr] = q[i];
		}
		else if(q[i].op==1)
		{
			if(q[i].k<=mid) ql[++cntl] = q[i],change(q[i].l,q[i].r,-1);
			else qr[++cntr] = q[i];
		}
		else
		{
			tmp = ask(q[i].l);
			if(tmp<q[i].k) q[i].k-=tmp,qr[++cntr] = q[i];
			else ql[++cntl] = q[i];
		}
	}
	for(int i = 1;i<=cntl;i++)
	{
		q[x+i-1] = ql[i];
		if(ql[i].op==0) change(ql[i].l,ql[i].r,-1);
		else if(ql[i].op==1) change(ql[i].l,ql[i].r,1);
	}
	for(int i = 1;i<=cntr;i++)
		q[x+cntl+i-1] = qr[i];
	if(cntl) solve(l,mid,x,x+cntl-1);
	if(cntr) solve(mid+1,r,x+cntl,y);
}
vector<pair<int,pair<int,int>>> vec1[N],vec2[N];
#define x first
#define y second
signed main()
{
//	freopen("1.in","r",stdin);
//	freopen("1.out","w",stdout);
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); 
	cin>>n>>m1>>m2;
	for(int i = 1,u,v;i<n;i++)
		cin>>u>>v,g[u].push_back(v),g[v].push_back(u);
	dfs1(1,0),dfs2(1,1);
	while(m1--)
	{
		int x,y,w;
		cin>>x>>y>>w;
		if(dfn[x]>dfn[y]) swap(x,y);
		if(dfn[x]<=dfn[y]&&dfn[y]<dfn[x]+sz[x])
		{
			int z = jump(y,x);
			if(dfn[z]>1) vec1[1].push_back({w,{dfn[y],dfn[y]+sz[y]-1}}),vec1[dfn[z]].push_back({-w,{dfn[y],dfn[y]+sz[y]-1}});
			if(dfn[z]+sz[z]<=n)	vec1[dfn[y]].push_back({w,{dfn[z]+sz[z],n}}),vec1[dfn[y]+sz[y]].push_back({-w,{dfn[z]+sz[z],n}});
		}
		else vec1[dfn[x]].push_back({w,{dfn[y],dfn[y]+sz[y]-1}}),vec1[dfn[x]+sz[x]].push_back({-w,{dfn[y],dfn[y]+sz[y]-1}});
	}
	for(int i = 1,x,y,k;i<=m2;i++)
	{
		cin>>x>>y>>k;
		if(dfn[x]>dfn[y]) swap(x,y);
		vec2[dfn[x]].push_back({i,{dfn[y],k}});
	}
	for(int i = 1;i<=n;i++)
	{
		for(auto _:vec1[i])
		{
			int w = _.x,l = _.y.x,r = _.y.y;
			if(w<0) q[++cnt] = (node){i,1,l,r,-w};
			else q[++cnt] = (node){i,0,l,r,w};
		}
		for(auto _:vec2[i])
		{
			int id = _.x,p = _.y.x,k = _.y.y;
			q[++cnt] = (node){id,2,p,p,k};
		}
	}
	solve(0,1e9,1,cnt);
	for(int i = 1;i<=m2;i++) cout<<ans[i]<<'\n';
	return 0;
}

如果全开 long long 的话就会全 TLE/MLE。

2024/8/4 15:57
加载中...