题目大意:给定一棵树,一开始每个点都是黑点,多次改变某个点的状态或询问距离最远的两个黑点的距离
《珍爱生命远离STL可是我还是可耻地用了STL系列》
传说中的动态树分治。。。其实并没有那么神嘛= =
↑别听这傻瓜瞎说这货被STL卡了一天QAQ
我们把分治过程中遍历过的重心都连起来 上一层的重心链接下一层的重心 可以得到一棵新的树
下面我们开始讨论这棵新树
显然这棵树的高度不会超过O(logn)
然后我们每个节点开两个堆
第一个堆记录子树中所有节点到父亲节点的距离
第二个堆记录所有子节点的堆顶
那么一个节点的堆2中的最大和次大加起来就是子树中经过这个节点的最长链
然后我们最后开一个全局的堆,记录所有堆2中最大值和次大值之和
那么全局的堆顶就是答案
修改啥的自己YY吧有益身心健康QAQ QAQ QAQ
这内存卡的飞起啊- -
#include
#include
#include
#include
#include
#define M 100100
using namespace std;
struct Priority_Queue{
priority_queue heap,delmark;
void Insert(int x)
{
heap.push(x);
}
void Erase(int x)
{
delmark.push(x);
}
void Pop()
{
while( delmark.size() && heap.top()==delmark.top() )
heap.pop(),delmark.pop();
heap.pop();
}
int Top()
{
while( delmark.size() && heap.top()==delmark.top() )
heap.pop(),delmark.pop();
return heap.top();
}
int Second_Top()
{
int temp=Top();Pop();
int re=Top();Insert(temp);
return re;
}
int Size()
{
return heap.size()-delmark.size();
}
}s1[M],s2[M],ans;
struct abcd{
int to,next;
bool ban;
}table[M<<1];
int head[M],tot=1;
int n,m,cnt;
int fa[M];
bool status[M];
int log_2[M<<1],dpt[M],pos[M],a[M<<1][20],T;
void Add(int x,int y)
{
table[++tot].to=y;
table[tot].next=head[x];
head[x]=tot;
}
int Get_Size(int x,int from)
{
int i,re=1;
for(i=head[x];i;i=table[i].next)
{
if(table[i].ban||table[i].to==from)
continue;
re+=Get_Size(table[i].to,x);
}
return re;
}
int Get_Centre_Of_Gravity(int x,int from,int size,int &cg)
{
int i,re=1,flag=true;
for(i=head[x];i;i=table[i].next)
{
if(table[i].ban||table[i].to==from)
continue;
int temp=Get_Centre_Of_Gravity(table[i].to,x,size,cg);
if(temp<<1>size)
flag=false;
re+=temp;
}
if(size-re<<1>size)
flag=false;
if(flag) cg=x;
return re;
}
void DFS(int x,int from,int dpt,Priority_Queue &s)
{
int i;
s.Insert(dpt);
for(i=head[x];i;i=table[i].next)
{
if(table[i].ban||table[i].to==from)
continue;
DFS(table[i].to,x,dpt+1,s);
}
}
void Insert(Priority_Queue &s)
{
if(s.Size()>=2)
{
int temp=s.Top()+s.Second_Top();
ans.Insert(temp);
}
}
void Erase(Priority_Queue &s)
{
if(s.Size()>=2)
{
int temp=s.Top()+s.Second_Top();
ans.Erase(temp);
}
}
int Tree_Divide_And_Conquer(int x)
{
int i,size,cg;size=Get_Size(x,0);
Get_Centre_Of_Gravity(x,0,size,cg);
s2[cg].Insert(0);
for(i=head[cg];i;i=table[i].next)
if(!table[i].ban)
{
table[i].ban=table[i^1].ban=true;
Priority_Queue s;
DFS(table[i].to,0,1,s);
int temp=Tree_Divide_And_Conquer(table[i].to);
fa[temp]=cg;s1[temp]=s;
s2[cg].Insert(s1[temp].Top());
}
Insert(s2[cg]);
return cg;
}
void DFS(int x,int from)
{
int i;
a[pos[x]=++T][0]=dpt[x]=dpt[from]+1;
for(i=head[x];i;i=table[i].next)
if(table[i].to!=from)
{
DFS(table[i].to,x);
a[++T][0]=dpt[x];
}
}
int LCA_Depth(int x,int y)
{
x=pos[x];y=pos[y];
if(x>y) swap(x,y);
int L=log_2[y-x+1];
return min(a[x][L],a[y-(1<>n;cnt=n;
for(i=1;i>1]+1;
for(j=1;j<=log_2[T];j++)
for(i=1;i+(1<>m;
for(i=1;i<=m;i++)
{
scanf("%s",p);
if(p[0]=='G')
{
if(cnt<=1)
printf("%d\n",cnt-1);
else
printf("%d\n",ans.Top());
}
else
{
scanf("%d",&x);
if(status[x]==true)
{
--cnt;status[x]=false;
Turn_Off(x);
}
else
{
++cnt;status[x]=true;
Turn_On(x);
}
}
}
return 0;
}