two
考场写了一个神奇的树链剖分过了???
我的做法简单来讲就是按照题意模拟,对于一条边求出它在另一棵树上可以 b a n ban ban掉的边,然后对于每条重链开 v e c t o r vector vector线段树维护可以删掉的边,修改的时候参考标记永久化即可。
时间复杂度摊下来是 O ( n l o g n 2 ) O(nlogn^2) O(nlogn2)
本来一点都不毒瘤但本地测大数据的时候会爆栈于是写了个bfs版的
代码:
#include<bits/stdc++.h>
#define ri register int
#define lc (p<<1)
#define rc (p<<1|1)
#define mid (l+r>>1)
#define pb push_back
using namespace std;
inline int read(){
int ans=0;
char ch=getchar();
while(!isdigit(ch))ch=getchar();
while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar();
return ans;
}
const int N=2e5+5;
priority_queue<int,vector<int>,greater<int> >q[2];
int n,que[N],hd,tl;
struct Node{
int x,y;};
struct Tree{
vector<int>e[N],S[N<<2];
bool vis[N];
Node G[N];
int siz[N],fa[N],hson[N],dep[N],top[N],num[N],pred[N],tot;
Tree(){
tot=dep[1]=fa[1]=0;
memset(hson,0,sizeof(hson));
memset(G,0,sizeof(G));
memset(vis,0,sizeof(vis));
}
void bfs(){
memset(que,0,sizeof(que));
que[hd=tl=1]=1;
while(hd<=tl){
int p=que[hd++];
siz[p]=1;
for(ri i=0,v;i<e[p].size();++i){
if((v=e[p][i])==fa[p])continue;
fa[v]=p,dep[v]=dep[p]+1,que[++tl]=v;
}
}
for(ri i=n,p;i>1;--i){
p=que[i],siz[fa[p]]+=siz[p];
if(siz[p]>siz[hson[fa[p]]])hson[fa[p]]=p;
}
for(ri i=1,p;i<=n;++i){
p=que[i];
if(hson[fa[p]]^p)top[p]=p;
else top[p]=top[fa[p]];
}
que[hd=tl=n]=1;
for(ri i=1;i<=n;++i){
int p=que[hd++];
pred[num[p]=++tot]=p;
if(!hson[p])continue;
for(ri i=0,v;i<e[p].size();++i){
if((v=e[p][i])==fa[p]||v==hson[p])continue;
que[--hd]=v;
}
que[--hd]=hson[p];
}
}
inline int lca(int x,int y){
while(top[x]^top[y]){
if(dep[top[x]]<dep[top[y]])swap(x,y);
x=fa[top[x]];
}
return dep[x]<dep[y]?x:y;
}
inline void update(int p,int l,int r,int ql,int qr,int v){
if(ql>r||qr<l)return;
if(ql<=l&&r<=qr){
S[p