Description
Arietta 的命运与她的妹妹不同,在她的妹妹已经走进学院的时候,她仍然留在山村中。
但是她从未停止过和恋人 Velding 的书信往来。一天,她准备去探访他。
对着窗外的阳光,临行前她再次弹起了琴。
她的琴的发声十分特殊。
让我们给一个形式化的定义吧。
所有的 n 个音符形成一棵由音符 C ( 1 号节点) 构成的有根树,每一个音符有一个音高 Hi 。
Arietta 有 m 个力度,第 i 个力度能弹出 Di 节点的子树中,音高在 [Li,Ri] 中的任意一个音符。
为了乐曲的和谐,Arietta 最多会弹奏第 i 个力度 Ti 次。
Arietta 想知道她最多能弹出多少个音符。
Input
输入共 m + 3 行。
第一行两个整数 n, m ,意义如题目所述。
第二行 n - 1 个整数 Pi ,表示节点 i ( i = 2 . . . n ) 的父亲节点的编号。
第三行 n 个整数 Hi 。
接下来的 m 行,每行四个整数 Li,Ri,D,Ti
Output
输出一个整数表示 Arietta 最多能弹奏多少音符。
数据范围与约定
对于 100% 的数据,1 ≤ n, m ≤ 10000 。
对于所有数据,1 ≤ Hi , Ti , Pi ≤ n, 1 ≤ Li ≤ Ri ≤ n 。
在树上做一次线段树合并(需要可持久化),得到每颗子树对应的音符集合,然后在线段树上查出对应的区间,优化建图跑最大流
#include<cstdio> #include<algorithm> const int N=10007; int n,m,idp=0; int min(int a,int b){return a<b?a:b;} namespace mxf{ struct edge{ int to,nx,v; }e[N*150]; int ep=2; int S,T,h[N*100],q[N*100],e0[N*100]; void ae(int a,int b,int c){ e[ep]=(edge){b,e0[a],c};e0[a]=ep++; e[ep]=(edge){a,e0[b],0};e0[b]=ep++; } bool bfs(){ for(int i=1;i<=idp;++i)h[i]=0; int ql=0,qr=0; h[q[++qr]=S]=1; while(ql!=qr){ int w=q[++ql]; if(w==T)return 1; for(int i=e0[w];i;i=e[i].nx)if(e[i].v){ int u=e[i].to; if(!h[u])h[q[++qr]=u]=h[w]+1; } } return 0; } int dfs(int w,int f){ if(w==T)return f; int c,used=0; for(int i=e0[w];i;i=e[i].nx)if(e[i].v){ int u=e[i].to; if(h[u]!=h[w]+1)continue; c=dfs(u,min(e[i].v,f-used)); e[i].v-=c,e[i^1].v+=c,used+=c; if(f==used)return f; } h[w]=0; return used; } int maxflow(){ int s=0; while(bfs())s+=dfs(S,n); return s; } } namespace sgt{ int ch[N*100][2],rt[N]; int build(int x,int L,int R){ int w=++idp; if(L<R){ int M=(L+R)>>1; if(x<=M)ch[w][0]=build(x,L,M); else ch[w][1]=build(x,M+1,R); }else mxf::ae(w,mxf::T,1); return w; } int get(int w,int l,int r,int L,int R){ if(!w||l<=L&&R<=r)return w; int M=(L+R)>>1; if(r<=M||!ch[w][1])return get(ch[w][0],l,r,L,M); if(l>M||!ch[w][0])return get(ch[w][1],l,r,M+1,R); int u=++idp; ch[u][0]=get(ch[w][0],l,r,L,M); ch[u][1]=get(ch[w][1],l,r,M+1,R); return u; } int mg(int w1,int w2){ if(w1&&w2){ int w=++idp; ch[w][0]=mg(ch[w1][0],ch[w2][0]); ch[w][1]=mg(ch[w1][1],ch[w2][1]); return w; } return w1|w2; } } namespace tree{ int es[N],enx[N],e0[N],h[N],hs[N],id[N][2],ep=2; void f1(int w){ using namespace sgt; rt[w]=build(h[w],1,n); for(int i=e0[w];i;i=enx[i]){ int u=es[i]; f1(u); int ll=idp+1; rt[w]=mg(rt[w],rt[u]); } } void init(){ for(int i=2,f;i<=n;++i){ scanf("%d",&f); es[ep]=i;enx[ep]=e0[f];e0[f]=ep++; } for(int i=1;i<=n;++i)scanf("%d",h+i),hs[i]=h[i]*(n+1)+i; std::sort(hs+1,hs+n+1); for(int i=1;i<=n;++i)h[i]=std::lower_bound(hs+1,hs+n+1,h[i]*(n+1)+i)-hs; mxf::S=++idp; mxf::T=++idp; f1(1); for(int i=1;i<=m;++i){ int l,r,d,t; scanf("%d%d%d%d",&l,&r,&d,&t); l=std::lower_bound(hs+1,hs+n+1,l*(n+1))-hs; r=std::upper_bound(hs+1,hs+n+1,(r+1)*(n+1))-hs-1; if(l<=r)mxf::ae(mxf::S,sgt::get(sgt::rt[d],l,r,1,n),t); } for(int i=3;i<=idp;++i)for(int d=0;d<2;++d)if(sgt::ch[i][d])mxf::ae(i,sgt::ch[i][d],n); } } int main(){ scanf("%d%d",&n,&m); tree::init(); printf("%d\n",mxf::maxflow()); return 0; }