社区讨论
求条。
P5314[Ynoi2011] ODT参与者 2已保存回复 3
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 3 条
- 当前快照
- 1 份
- 快照标识符
- @mj9mav8l
- 此快照首次捕获于
- 2025/12/17 14:15 2 个月前
- 此快照最后确认于
- 2025/12/20 09:35 2 个月前
诡异地WA在500000多行。
没T。
CPP#include<bits/stdc++.h>
#define lowbit(x) (x&(-x))
using namespace std;
const int N=1e6+7;
int n,m,idx,opt,u,v,k,head[N],to[N*2],last[N*2],w[N];
int dfn[N],tot,top[N],son[N],sz[N],t[N],dep[N],f[N];
pair<pair<int,int>,pair<int,int> > qus[N];
struct balance_tree{
vector<int> v,rk;
int bin_s(int x){
int l=0,r=rk.size()-1,mid=0,ans=0;
while(l<=r){
mid=l+r>>1;
if(rk[mid]<=x) ans=mid,l=mid+1;
else r=mid-1;
}
return ans;
}
void add(int k,int x){
k=bin_s(k);
while(k<v.size()) v[k]+=x,k+=lowbit(k);
}
int ask(int k){
k=bin_s(k);
int res=0;
while(k) res+=v[k],k-=lowbit(k);
return res;
}
}a[N];
inline void add(int u,int v){
++idx;
to[idx]=v,last[idx]=head[u],head[u]=idx;
}
inline void dfs(int u,int fa){
int mx=0;
sz[u]=1,dep[u]=dep[fa]+1,f[u]=fa;
for(int i=head[u];i;i=last[i]){
if(to[i]!=fa){
dfs(to[i],u),sz[u]+=sz[to[i]];
if(sz[to[i]]>mx) mx=sz[to[i]],son[u]=to[i];
}
}
}
inline void dfs_(int u,int fa,int op){
dfn[u]=++tot;
if(op) top[u]=top[fa];
else top[u]=u;
for(int i=head[u];i;i=last[i]){
if(to[i]==son[u]) dfs_(to[i],u,1);
}
for(int i=head[u];i;i=last[i]){
if(to[i]!=fa&&to[i]!=son[u]) dfs_(to[i],u,0);
}
}
inline void plus_(int k,int x){
while(k<=n) t[k]+=x,k+=lowbit(k);
}
inline int ask(int k){
int res=0;
while(k) res+=t[k],k-=lowbit(k);
return res;
}
inline void lca(int u,int v,int k,bool op){
while(top[u]!=top[v]){
if(dep[top[u]]<dep[top[v]]) swap(u,v);
if(op){
a[f[top[u]]].add(ask(dfn[top[u]])
+w[top[u]],-1);
}
plus_(dfn[top[u]],k),plus_(dfn[u]+1,-k);
if(!op){
a[f[top[u]]].rk.push_back(ask(dfn[top[u]])
+w[top[u]]);
}
else{
a[f[top[u]]].add(ask(dfn[top[u]])
+w[top[u]],1);
}
u=f[top[u]];
}
if(dep[u]<dep[v]) swap(u,v);
plus_(dfn[v],k),plus_(dfn[u]+1,-k);
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
cin>>n>>m;
for(int i=1;i<=n;i++) cin>>w[i];
for(int i=1;i<n;i++){
cin>>u>>v;
add(u,v),add(v,u);
}
dfs(1,0),dfs_(1,0,0);
for(int i=1;i<=n;i++){
a[i].rk.clear(),a[i].v.clear();
a[i].rk.push_back(0),a[i].v.push_back(0);
a[i].rk.push_back(w[i]),a[i].v.push_back(0);
for(int j=head[i];j;j=last[j]){
a[i].rk.push_back(w[to[j]]);
a[i].v.push_back(0);
}
}
for(int i=1;i<=m;i++){
cin>>opt>>u;
if(opt==1){
cin>>v>>k,qus[i]={{opt,u},{v,k}};
lca(u,v,k,0);
}
else{
cin>>k,qus[i]={{opt,u},{0,k}};
if(son[u]){
a[u].rk.push_back(ask(dfn[son[u]])
+w[son[u]]);
}
if(f[u]) a[u].rk.push_back(ask(dfn[f[u]])+w[f[u]]);
a[u].rk.push_back(ask(dfn[u])+w[u]);
}
}
for(int i=1;i<=n;i++){
sort(a[i].rk.begin(),a[i].rk.end());
while(a[i].v.size()<a[i].rk.size()) a[i].v.push_back(0);
for(int j=head[i];j;j=last[j]){
if(to[j]!=f[i]&&to[j]!=son[i]){
a[i].add(w[to[j]],1);
}
}
t[i]=0;
}
/*for(int i=0;i<11;i++) cout<<a[1].v[i]<<" ";
cout<<'\n'<<a[1].ask(5);*/
for(int i=1;i<=m;i++){
opt=qus[i].first.first;
u=qus[i].first.second;
v=qus[i].second.first;
k=qus[i].second.second;
if(opt==1) lca(u,v,k,1);
else{
if(son[u]){
a[u].add(ask(dfn[son[u]])+w[son[u]],1);
}
if(f[u]) a[u].add(ask(dfn[f[u]])+w[f[u]],1);
a[u].add(ask(dfn[u])+w[u],1);
int l=0,r=a[u].rk.size()-1,mid=0,ans=0;
while(l<=r){
mid=l+r>>1;
if(a[u].ask(a[u].rk[mid])>=k) ans=a[u].rk[mid],r=mid-1;
else l=mid+1;
}
cout<<ans<<'\n';
if(son[u]){
a[u].add(ask(dfn[son[u]])+w[son[u]],-1);
}
if(f[u]) a[u].add(ask(dfn[f[u]])+w[f[u]],-1);
a[u].add(ask(dfn[u])+w[u],-1);
}
}
return 0;
}
回复
共 3 条回复,欢迎继续交流。
正在加载回复...