社区讨论
萌新刚学oi,简单树剖求调,已过样例,WA加MLE,悬赏一关注
P2486[SDOI2011] 染色参与者 3已保存回复 4
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 4 条
- 当前快照
- 1 份
- 快照标识符
- @lo3do0cn
- 此快照首次捕获于
- 2023/10/24 04:56 2 年前
- 此快照最后确认于
- 2023/10/24 04:56 2 年前
CPP
#include<bits/stdc++.h>
#define N 100010
using namespace std;
int to[N],nex[N],beg[N],e,rev[N];
int w[N];
int lc,rc;
struct note {
int l,r,cl,cr;
int sum,lazy;
} tree[N*4];
inline void add(int x,int y) {
to[++e]=y;
nex[e]=beg[x];
beg[x]=e;
}
inline void push_up(int x) {
tree[x].sum=tree[x<<1].sum+tree[x<<1|1].sum;
tree[x].cl=tree[x<<1].cl;
tree[x].cr=tree[x<<1|1].cr;
if(tree[x<<1].cr==tree[x<<1|1].cl)tree[x].sum--;
}
inline void build(int x,int l,int r) {
int mid=l+r>>1;
tree[x].l=l,tree[x].r=r,tree[x].lazy=-1;
if(l==r) {
tree[x].cl=tree[x].cr=w[rev[l]];
tree[x].sum=1;
return ;
}
build(x<<1,l,mid);
build(x<<1|1,mid+1,r);
push_up(x);
}
int fa[N],deep[N],Snum[N],son[N];
inline void dfs1(int x,int f) {
deep[x]=deep[f]+1,fa[x]=f;
Snum[x]=1;
int maxn=-1;
for(int i=beg[x]; i; i=nex[i]) {
int y=to[i];
if(y==f)continue;
dfs1(y,x);
Snum[x]+=Snum[y];
if(Snum[y]>maxn)maxn=Snum[y],son[x]=y;
}
}
int top[N],name[N],cnt;
inline void dfs2(int x,int Top) {
top[x]=Top;
name[x]=++cnt;
rev[cnt]=x;
if(!son[x])return ;
dfs2(son[x],Top);
for(int i=beg[x]; i; i=nex[i]) {
int y=to[i];
if(y==fa[x]||y==son[x])continue;
dfs2(y,y);
}
}
inline void pushdown(int x) {
if(tree[x].lazy==-1)return ;
tree[x<<1].lazy=tree[x<<1|1].lazy=tree[x].lazy;
tree[x<<1].sum=tree[x<<1|1].sum=1;
tree[x<<1].cl=tree[x<<1].cr=tree[x].cl;
tree[x<<1|1].cl=tree[x<<1|1].cr=tree[x].cr;
tree[x].lazy=-1;
}
inline int query(int x,int L,int R) {
if(L<=tree[x].l&&tree[x].r<=R) {
if(tree[x].l==L)lc=tree[x].cl;
if(tree[x].r==R)rc=tree[x].cr;
return tree[x].sum;
}
pushdown(x);
int mid=tree[x].l+tree[x].r>>1;
if(L<=mid)return query(x<<1,L,R);
if(R>mid)return query(x<<1|1,L,R);
int ans=query(x<<1,L,R)+query(x<<1|1,L,R);
if(tree[x<<1].cr==tree[x<<1|1].cl)ans--;
return ans;
}
inline void up_date(int x,int L,int R,int k) {
if(L<=tree[x].l&&tree[x].r<=R) {
tree[x].cl=tree[x].cr=k;
tree[x].sum=tree[x].lazy=1;
return ;
}
pushdown(x);
int mid=tree[x].l+tree[x].r>>1;
if(L<=mid)up_date(x<<1,L,R,k);
if(R>mid)up_date(x<<1|1,L,R,k);
push_up(x);
}
inline int Query(int x,int y) {
int ans=0;
int ans1=0,ans2=0;
while(top[x]!=top[y]) {
if(deep[top[x]]<deep[top[y]])swap(x,y),swap(ans1,ans2);
ans+=query(1,name[top[x]],name[x]);
if(rc==ans1)ans--;
ans1=lc;
x=fa[top[x]];
}
if(deep[x]>deep[y])swap(x,y),swap(ans1,ans2);
ans+=query(1,name[x],name[y]);
if(lc==ans1)ans--;
if(rc==ans2)ans--;
return ans;
}
inline void update(int x,int y,int k) {
while(top[x]!=top[y]) {
if(deep[top[x]]<deep[top[y]])swap(x,y);
up_date(1,name[top[x]],name[x],k);
x=fa[top[x]];
}
if(deep[x]>deep[y])swap(x,y);
up_date(1,name[x],name[y],k);
return ;
}
int main() {
int n,m;
cin>>n>>m;
int x,y;
for(int i=1; i<=n; i++) {
cin>>w[i];
}
for(int i=1; i<n; i++) {
cin>>x>>y;
add(x,y);
add(y,x);
}
dfs1(1,0);
dfs2(1,1);
build(1,1,n);
while(m--) {
char op;
int x,y,z;
cin>>op;
if(op=='Q') {
cin>>x>>y;
cout<<Query(x,y)<<"\n";
} else {
cin>>x>>y>>z;
update(x,y,z);
}
}
return 0;
}
回复
共 4 条回复,欢迎继续交流。
正在加载回复...