代码比较长,简述一下问题:
交上去以后 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;
}