小菜鸡点分树莫名 RE 报错求助QAQ
查看原帖
小菜鸡点分树莫名 RE 报错求助QAQ
35891
huangzirui楼主2020/8/1 20:14

代码比较长,简述一下问题:

交上去以后 RE + TLE 很迷,于是搞了一组数据:

数据

自测了一下报错:

*** Error in `./P2056': free(): invalid pointer: 0x00000000009d4e68 ***
...

后续报错

查了一下好像是指针问题,但是基本没有用。。。目前用了的也貌似没什么问题,求 dalao 查一下qaq

算法主要用点分树,每个点上两个 set 维护一下最大值和修改。

#include <bits/stdc++.h>
#define ll long long
#define Mid ((L+R)>>1)
using namespace std;
typedef pair<int,int> pii;
inline int read(){
	char c;int x=0;int b=1;do{c=getchar();if(c==45)b=-1;}while(c>57||c<48);
	do x=x*10+c-48,c=getchar();while(c<=57&&c>=48);x*=b;return x;
}
const int maxn=1000010;
struct edge{
	int next,to;
}a[maxn*2];
int head[maxn],len;
void add(int x,int y){
	a[++len]={head[x],y};
	head[x]=len;
}
int i,j,k,n,m,deep[maxn],FA[maxn][21];
void dfs(int now,int fa){
	deep[now]=deep[fa]+1;
	FA[now][0]=fa;
	for(int i=head[now];i;i=a[i].next){
		int u=a[i].to;
		if(u==fa)continue;
		dfs(u,now);
	}
}
void LCA(){
	for(int j=1;j<=20;j++)
		for(int i=1;i<=n;i++)
			FA[i][j]=FA[FA[i][j-1]][j-1];
}
int size[maxn],big[maxn],vis[maxn],MAX,root,SIZE;
void getsize(int now,int fa){
	size[now]=1;big[now]=0;
	for(int i=head[now];i;i=a[i].next){
		int u=a[i].to;
		if(u==fa || vis[u])continue;
		getsize(u,now);
		size[now]+=size[u];
		big[now]=max(big[now],size[u]);
	}big[now]=max(big[now],SIZE-size[now]);
	if(big[now]<MAX){
		MAX=big[now];
		root=now;
	}
}
vector<pii>V[maxn];
multiset<int>S[maxn],S2[maxn];
void build(int now,int fa){
	vis[now]=1;
	for(int i=head[now];i;i=a[i].next){
		int u=a[i].to;
		if(u==fa || vis[u])continue;
		SIZE=size[u];MAX=1e9;
		getsize(u,now);
		getsize(root,now);
		V[root].push_back((pii){now,0});
		for(int j=0;j<V[now].size();j++)
			V[root].push_back(V[now][j]);
		build(root,now);
	}
}
int lca(int x,int y){
	if(deep[x]<deep[y])swap(x,y);
	for(int j=20;j>=0;j--)
		if(deep[FA[x][j]]>=deep[y])
			x=FA[x][j];
	if(x==y)return x;
	for(int j=20;j>=0;j--)
		if(FA[x][j]!=FA[y][j])
			x=FA[x][j],y=FA[y][j];
	return FA[x][0];
}
multiset<int>::iterator it;
int set_max(multiset<int> x,int op=0){
	if(x.empty() && op)return -1;
	if(x.empty())return 0;
	it=x.end();it--;
	return (*it);
}
int get_ans(multiset<int> x){
	int sum1=0,sum2=0;
	sum1=set_max(x);
	if(sum1){
		x.erase(x.find(sum1));
		sum2=set_max(x,1);
		x.insert(sum1);
	}
	if(sum2==-1)return 0;
	return sum1+sum2;
}
multiset<int>ans;
int is[maxn];
int ROOT=root,NUM;
void change(int x){
	if(is[x]){
		is[x]^=1;
		ans.erase(ans.find(get_ans(S2[x])));
		S2[x].insert(0);
		ans.insert(get_ans(S2[x]));
		int last=x;
		for(int i=0;i<V[x].size();i++){
			int u=V[x][i].first,len=V[x][i].second,MAX=set_max(S[last]);bool B=0;
			if(MAX<len)B=1;
			S[last].insert(len);
			if(B){
				ans.erase(ans.find(get_ans(S2[u])));
				S2[u].erase(MAX);
				S2[u].insert(len);
				ans.insert(get_ans(S2[u]));
			}last=u;
		}NUM--;
	}else{
		is[x]^=1;
		ans.erase(ans.find(get_ans(S2[x])));
		S2[x].erase(S2[x].find(0));
		ans.insert(get_ans(S2[x]));
		int last=x;
		for(int i=0;i<V[x].size();i++){
			int u=V[x][i].first,len=V[x][i].second;bool B=0;
			if(set_max(S[last])==len)B=1;
			S[last].erase(S[last].find(len));
			if(B){
				ans.erase(ans.find(get_ans(S2[u])));
				S2[u].erase(S2[u].find(len));
				if(!S[last].empty())S2[u].insert(set_max(S[last]));
				ans.insert(get_ans(S2[u]));
			}last=u;
		}NUM++;
	}
}
int main() {
	freopen("P2056.in","r",stdin);
	freopen("P2056.out","w",stdout);
	n=read();
	for(i=1;i<n;i++){
		int x=read(),y=read();
		add(x,y);add(y,x);
	}
	dfs(1,0);LCA();
	SIZE=n;MAX=1e9;
	getsize(1,0);
	ROOT=root;
	getsize(root,0);
	build(root,0);
	for(i=1;i<=n;i++){
		int last=i;
		for(j=0;j<V[i].size();j++){
			int u=V[i][j].first,z=lca(i,u),len=deep[i]+deep[u]-2*deep[z];
			V[i][j].second=len;
			S[last].insert(len);
			last=u;
		}
	}
	for(i=1;i<=n;i++){
		S2[i].insert(0);
		if(i==ROOT)continue;
		int u=V[i][0].first;
		S2[u].insert(set_max(S[i]));
	}
	for(i=1;i<=n;i++){
		int sum=get_ans(S2[i]);
		ans.insert(sum);
	}
	m=read();
	for(i=1;i<=m;i++){
		string S;int x;
		cin>>S;
		if(S=="G"){
			if(NUM!=n)printf("%d\n",set_max(ans,1));
			else puts("-1");
		}else{
			x=read();
			change(x);
		}
	}
	//cerr << 1.0*clock()/CLOCKS_PER_SEC << endl;
	return 0;
}
2020/8/1 20:14
加载中...