悬关求调
查看原帖
悬关求调
847286
CangerYumo楼主2024/3/21 11:02

WA on test #4

#include<bits/stdc++.h>
#define int long long
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
using namespace std;
int n,q,k,pt;
int x,y,cnt,dfn[200005],dep[200005],mx[800005],tag[800005],siz[200005];
vector<int> task_id[200005];
vector<int> task_k[200005];
vector<int> t[200005];
bool vis[200005];int reveal[200005];
inline void _init(int now,int dp){//预处理节点深度,dfs序,子树大小
	//printf("_init(%d,%d);",now,dp);cout<<endl;
	dfn[now]=++cnt;dep[dfn[now]]=dp;vis[now]=1;siz[now]=1;
	for(int i=0;i<t[now].size();i++){
		if(vis[t[now][i]]) continue;
		_init(t[now][i],dp+1);
		siz[now]+=siz[t[now][i]];
	}
	return;
}
inline void update(int rt){
	mx[rt]=max(mx[rt<<1],mx[rt<<1|1]);
	return;
}
void build(int l,int r,int rt){
	if(l==r){
		mx[rt]=dep[l];
		//cout<<"["<<l<<','<<r<<"]->"<<mx[rt]<<endl;
		return;
	}
	int mid=(l+r)>>1;
	build(lson);build(rson);
	update(rt);
	//cout<<"["<<l<<','<<r<<"]->"<<mx[rt]<<endl;
	return;
}
inline void color(int l,int r,int rt,int c){
	mx[rt]+=c;
	tag[rt]+=c;
	return;
}
inline void ph_tg(int l,int r,int rt){
	if(tag[rt]==0){
		return;
	}
	int mid=(l+r)>>1;
	color(lson,tag[rt]);
	color(rson,tag[rt]);
	tag[rt]=0;
	return;
}
void modify(int l,int r,int rt,int c){
	if(x<=l&&r<=y){
		color(l,r,rt,c);
		return;
	}
	ph_tg(l,r,rt);
	int mid=(l+r)>>1;
	if(x<=mid) modify(lson,c);
	if(y>mid) modify(rson,c);
	update(rt);
	return;
}
int query(int l,int r,int rt){
	if(x<=l&&r<=y){
		return mx[rt];
	}
	ph_tg(l,r,rt);
	int ans=0,mid=(l+r)>>1;
	if(x<=mid) ans=max(ans,query(lson));
	if(y>mid) ans=max(ans,query(rson));
	//printf("query(%d,%d,%d); ans:%d",l,r,rt,ans);cout<<endl;
	return ans;
}
inline void upd(int now,int pre,int dir){//dir 1表示向下走,2表示回溯
	if(now==pre) return;
	if(dir==1){
		x=1,y=n;modify(1,n,1,1);
		x=dfn[now],y=dfn[now]+siz[now]-1;modify(1,n,1,-2);
		//cout<<pre<<"->"<<now<<' '<<"["<<x<<","<<y<<"];"<<endl;
		//for(int i=1;i<=n*2;i++) cout<<mx[i]<<' ';
		//cout<<endl;
		//for(int i=1;i<=n*2;i++) cout<<tag[i]<<' ';
		//cout<<endl;
	}else{
		x=1,y=n;modify(1,n,1,-1);
		x=dfn[now],y=dfn[now]+siz[now]-1;modify(1,n,1,2);
		//cout<<now<<"->"<<pre<<' '<<"["<<x<<","<<y<<"];"<<endl;
	}
	//cout<<x<<" "<<y<<endl;
	return;
}
inline bool cmp(pair<int,int> a,pair<int,int> b){
	return a.first<b.first;
}
inline void deal(int now,int id){
	vector<pair<int,int> > intervals;//维护不可达的点的dfs序区间
	int rm;
	//printf("deal(%d,%d);",now,id);cout<<endl;
	for(int p=0;p<task_k[id].size();p++){
		rm=task_k[id][p];
		if(dfn[now]>dfn[rm]&&dfn[now]<dfn[rm]+siz[rm]){//要删除的点是now的祖先
			int fa;
			for(int i=0;i<t[rm].size();i++){//这里可以(必须?)优化成二分查找
				if(dfn[t[rm][i]]<=dfn[now]){
					fa=t[rm][i];
				}else{
					break;
				}
			}
			intervals.push_back({1,dfn[fa]-1});
			intervals.push_back({dfn[fa]+siz[fa],n});
			//cout<<"findfa:"<<fa<<endl;
		}else{//否则直接删除rm的子树
			intervals.push_back({dfn[rm],dfn[rm]+siz[rm]-1});
		}
	}
	sort(intervals.begin(),intervals.end(),cmp);
	int avai_l=1,avai_r=0,ans=0;//可用区间左右端点以及答案
	vector<pair<int,int> > together;//存储合并后的区间
	int at=-1;
	for(int i=0;i<intervals.size();i++){//注意这里,可能有锅
		if(at==-1){
			together.push_back(intervals[i]);
			at=0;
		}else if(together[at].second>=intervals[i].first-1){
			together[at].second=max(together[at].second,intervals[i].second);
		}else{
			together.push_back(intervals[i]);
			++at;
		}
	}
	//cout<<"at:"<<at<<endl;
	if(at!=-1){
		for(int i=0;i<=at;i++){
			//cout<<"Uh-huh?"<<endl;
			//cout<<i<<"->i"<<endl;
			if(i==0){
				avai_l=1;avai_r=together[0].first-1;
				if(avai_r>=avai_l){
					x=avai_l;y=avai_r;
					//cout<<"request:"<<"("<<x<<","<<y<<")"<<endl;
					ans=max(ans,query(1,n,1));
				}else{
					//cout<<"tried:"<<avai_l<<'~'<<avai_r<<endl;
				}
			}else{
				avai_l=together[i-1].second+1;
				avai_r=together[i].first-1;
				if(avai_r>=avai_l){
					x=avai_l;y=avai_r;
					//cout<<"request:"<<"("<<x<<","<<y<<")"<<endl;
					ans=max(ans,query(1,n,1));
				}
				else{
					//cout<<"tried:"<<avai_l<<'~'<<avai_r<<endl;
				}
			}
		}
		avai_l=together[at].second+1,avai_r=n;
		if(avai_r>=avai_l){
			x=avai_l,y=avai_r;
			//cout<<"request:"<<"("<<x<<","<<y<<")"<<endl;
			ans=max(ans,query(1,n,1));
		}
		else{
			//cout<<"tried:"<<avai_l<<'~'<<avai_r<<endl;
		}
	}else{
		x=1,y=n;
		ans=max(ans,query(1,n,1));
	}
	//cout<<"Ans:"<<ans<<endl;
	reveal[id]=ans;
	return;
}
void dfs(int now,int pre){//我们离线存储了询问,现在可以按照dfs序解决每个节点
	//cout<<"dfs("<<now<<","<<pre<<");"<<endl;
	upd(now,pre,1);int num=task_id[now].size();vis[now]=1;
	for(int p=0;p<num;p++){
		int id=task_id[now][p];
		deal(now,id);
	}
	for(int i=0;i<t[now].size();i++){
		if(vis[t[now][i]]) continue;
		dfs(t[now][i],now);
	}
	upd(now,pre,2);
	return;
}
signed main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	cin>>n>>q;int res=q;
	for(int i=1,u,v;i<n;i++){
		cin>>u>>v;
		t[u].push_back(v);
		t[v].push_back(u);
	}
	while(q--){
		cin>>pt>>k;
		task_id[pt].push_back(++cnt);
		for(int i=1,c;i<=k;i++){
			cin>>c;
			task_k[cnt].push_back(c);
		}
	}cnt=0;
	_init(1,0);
	build(1,n,1);
	// for(int i=1;i<=n;i++){
	// 	cout<<dfn[i]<<' ';
	// }cout<<endl;
	// for(int i=1;i<=n;i++){
	// 	cout<<dep[i]<<' ';
	// }cout<<endl;
	memset(vis,0,sizeof(vis));
	dfs(1,1);
	for(int i=1;i<=res;i++){
		cout<<reveal[i]<<endl;
	}
	return 0;
}
2024/3/21 11:02
加载中...