社区讨论
求调RE
P2542[AHOI2005] 航线规划参与者 1已保存回复 0
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @m69gblhb
- 此快照首次捕获于
- 2025/01/23 22:51 去年
- 此快照最后确认于
- 2025/11/04 10:47 4 个月前
CPP
#include<bits/stdc++.h>
#define ls (p<<1)
#define rs (ls|1)
#define pl pair<int,int>
using namespace std;
const int N=6e4+5,M=2e5+5;
int n,m,k,root,head[N],cnt;
int siz[N],son[N],dep[N],tot[N],id[N],idx,st[N];
struct nnd {
int to,next;
}eg[M<<1];
inline void add(const int& from,const int& to){
eg[cnt].to=to;
eg[cnt].next=head[from];
head[from]=cnt++;
}
inline void dfs1(const int& x,const int& fa){
st[x]=fa;
dep[x]=dep[fa]+1;
for(int i=head[x];~i;i=eg[i].next){
int to=eg[i].to;
if(to==fa){
continue;
}
dfs1(to,x);
siz[x]+=siz[to];
if(!son[x]||siz[to]>siz[son[x]]){
son[x]=to;
}
}
}
inline void dfs2(const int& x,const int& totx){
id[x]=++idx;
tot[x]=totx;
if(!son[x]){
return;
}
dfs2(son[x],totx);
for(int i=head[x];~i;i=eg[i].next){
int to=eg[i].to;
if(to!=st[x]&&to!=son[x]){
dfs2(to,to);
}
}
}
struct node {
int a,b;
int sum,lazy;
}tree[N<<2];
inline void up_tree(const int& p){
tree[p].sum=tree[ls].sum+tree[rs].sum;
}
inline void down_tree(const int& p){
if(!tree[p].lazy||tree[p].a==tree[p].b){
return;
}
tree[p].lazy=0;
tree[ls].lazy=1;
tree[ls].sum=0;
tree[rs].lazy=1;
tree[rs].sum=0;
}
inline void build_tree(const int& p,const int& x,const int& y){
tree[p].a=x;
tree[p].b=y;
if(x==y){
tree[p].sum=1;
return;
}
int mid=x+y>>1;
build_tree(ls,x,mid);
build_tree(rs,mid+1,y);
up_tree(p);
}
inline void change_tree(const int& p,const int& x,const int& y){
down_tree(p);
if(x<=tree[p].a&&tree[p].b<=y){
tree[p].lazy=1;
tree[p].sum=0;
return;
}
if(x<=tree[ls].b){
change_tree(ls,x,y);
}
if(tree[rs].a<=y){
change_tree(rs,x,y);
}
up_tree(p);
}
inline int get_tree(const int& p,const int& x,const int& y){
down_tree(p);
if(x<=tree[p].a&&tree[p].b<=y){
return tree[p].sum;
}
int ans=0;
if(x<=tree[ls].b){
ans+=get_tree(ls,x,y);
}
if(tree[rs].a<=y){
ans+=get_tree(rs,x,y);
}
return ans;
}
inline void change_lca(int x,int y){
if(x==y)return;
while(tot[x]!=tot[y]){
if(dep[tot[x]]<dep[tot[y]]){
swap(x,y);
}
int totx=tot[x];
change_tree(1,id[totx],id[x]);
x=st[totx];
}
if(dep[x]<dep[y]){
swap(x,y);
}
if(x!=y){
change_tree(1,id[y]+1,id[x]);
}
}
inline int get_lca(int x,int y){
if(x==y)return 0;
int ans=0;
while(tot[x]!=tot[y]){
if(dep[tot[x]]<dep[tot[y]]){
swap(x,y);
}
int totx=tot[x];
ans+=get_tree(1,id[totx],id[x]);
x=st[totx];
}
if(dep[x]<dep[y]){
swap(x,y);
}
if(x!=y){
ans+=get_tree(1,id[y]+1,id[x]);
}
return ans;
}
map<pl,bool>mp;
struct mmb {
int x,y,vis;
}A[M<<1],B[M<<1];
int fa[N];
void init(){
for(int i=1;i<=n;i++){
fa[i]=i;
siz[i]=1;
head[i]=-1;
}
cnt=idx=0;
}
inline int find(const int& x){
if(fa[x]==x){
return x;
} else {
return fa[x]=find(fa[x]);
}
}
stack<int>ans;
int main(){
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
cin>>n>>m;
init();
for(int i=1;i<=m;i++){
cin>>A[i].x>>A[i].y;
}
while(1){
int w,x,y;
cin>>w;
if(w==-1){
break;
}
k++;
cin>>B[k].x>>B[k].y;
mp[pl(B[k].x,B[k].y)]=1;
B[k].vis=w;
}
for(int i=1;i<=m;i++){
if(mp[pl(A[i].x,A[i].y)]||mp[pl(A[i].y,A[i].x)]){
A[i].vis=2;
continue;
}
int x=find(A[i].x),y=find(A[i].y);
if(x!=y) {
fa[y]=x;
add(A[i].x,A[i].y);
add(A[i].y,A[i].x);
} else {
A[i].vis=1;
}
}
dep[0]=-1;
dfs1(1,0);
dfs2(1,1);
build_tree(1,1,n);
for(int i=1;i<=m;i++){
if(A[i].vis==1){
change_lca(A[i].x,A[i].y);
}
}
for(int i=k;i;i--){
if(B[i].vis){
ans.push(get_lca(B[i].x,B[i].y));
} else {
change_lca(B[i].x,B[i].y);
}
}
while(ans.size()){
cout<<ans.top()<<"\n";
ans.pop();
}
return 0;
}
回复
共 0 条回复,欢迎继续交流。
正在加载回复...