首页 > 代码库 > BZOJ 2809: [Apio2012]dispatching [主席树 DFS序]
BZOJ 2809: [Apio2012]dispatching [主席树 DFS序]
传送门
题意:查询树上根节点值*子树中权值和$\le m$的最大数量 最大值是多少
求$DFS$序,然后变成区间中和$\le m$最多有几个元素,建主席树,然后权值线段树上二分就行了
$WA$:又把边表开小了.....
好吧我$zz$了有根树加无向边干什么....
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;#define lc(x) t[x].l#define rc(x) t[x].rtypedef long long ll;const int N=1e5+5;int read(){ char c=getchar();int x=0,f=1; while(c<‘0‘||c>‘9‘){if(c==‘-‘)f=-1; c=getchar();} while(c>=‘0‘&&c<=‘9‘){x=x*10+c-‘0‘; c=getchar();} return x*f;}int n,m,mp[N];struct Ninjia{ int w,li,id; bool operator <(const Ninjia &r)const{return w<r.w;}}a[N];inline bool cmpId(Ninjia a,Ninjia b){return a.id<b.id;}struct Edge{ int v,ne;}e[N<<1];int h[N],cnt;inline void ins(int u,int v){ cnt++; e[cnt].v=v;e[cnt].ne=h[u];h[u]=cnt; cnt++; e[cnt].v=u;e[cnt].ne=h[v];h[v]=cnt;}int L[N],R[N],dfc,pos[N];void dfs(int u,int fa){ L[u]=++dfc; pos[dfc]=u; for(int i=h[u];i;i=e[i].ne) if(e[i].v!=fa) dfs(e[i].v,u); R[u]=dfc;}struct Node{ int l,r,size; ll sum;}t[N*30];int sz,root[N];void fIns(int &x,int l,int r,int p){ t[++sz]=t[x];x=sz; t[x].size++; t[x].sum+=(ll)mp[p]; if(l==r) return; int mid=(l+r)>>1; if(p<=mid) fIns(lc(x),l,mid,p); else fIns(rc(x),mid+1,r,p);}int fQue(int x,int y,int l,int r,ll m){ //printf("fQue %d %d %d %d %d %d %lld %lld\n",x,y,l,r,t[x].size,t[y].size,t[x].sum,t[y].sum); if(l==r){ ll lsum=t[y].sum-t[x].sum; return lsum<=m ? t[y].size-t[x].size : 0; }else{ int mid=(l+r)>>1; ll lsum=t[lc(y)].sum-t[lc(x)].sum;//printf("lsum %lld %lld\n",lsum,m); if(m<=lsum) return fQue(lc(x),lc(y),l,mid,m); else return t[lc(y)].size-t[lc(x)].size+fQue(rc(x),rc(y),mid+1,r,m-lsum); }}int rt=0,u;int main(){ freopen("in","r",stdin); n=read();m=read(); for(int i=1;i<=n;i++){ u=read();if(u==0) rt=i; ins(u,i),a[i].w=read(),a[i].li=read(),a[i].id=i; } sort(a+1,a+1+n); for(int i=1;i<=n;i++) mp[i]=a[i].w,a[i].w=i; sort(a+1,a+1+n,cmpId); //for(int i=1;i<=n;i++) printf("a %d %d %d\n",a[i].id,a[i].w,mp[a[i].w]); dfs(rt,0); //for(int i=1;i<=n;i++) printf("LR %d %d %d\n",i,L[i],R[i]); //for(int i=1;i<=n;i++) printf("%d ",pos[i]);puts(""); for(int i=1;i<=n;i++) root[i]=root[i-1],fIns(root[i],1,n,a[pos[i]].w); ll ans=0; for(int i=1;i<=n;i++) ans=max(ans,(ll)a[i].li*fQue(root[L[i]-1],root[R[i]],1,n,m)); printf("%lld",ans);}
BZOJ 2809: [Apio2012]dispatching [主席树 DFS序]
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。