bzoj3681: Arietta(网络流)

传送门

 

主席树优化建图?

然而我连代码都看不懂

贴个题解好了->这里

  1 //minamoto
  2 #include<iostream>
  3 #include<cstdio>
  4 #include<cstring>
  5 #include<queue>
  6 #include<vector>
  7 #define inf 0x3f3f3f3f
  8 using namespace std;
  9 #define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
 10 char buf[1<<21],*p1=buf,*p2=buf;
 11 inline int read(){
 12     #define num ch-'0'
 13     char ch;bool flag=0;int res;
 14     while(!isdigit(ch=getc()))
 15     (ch=='-')&&(flag=true);
 16     for(res=num;isdigit(ch=getc());res=res*10+num);
 17     (flag)&&(res=-res);
 18     #undef num
 19     return res;
 20 }
 21 const int N=10005;
 22 int head[N*80],dep[N*80],cur[N*80],ver[N*240],edge[N*240],Next[N*240],tot=1;
 23 int fa[N],L[N*80],R[N*80],sz[N],son[N],rt[N],v[N];
 24 queue<int> q;vector<int> ch[N];int S,T,cnt,n,m;
 25 inline void add(int u,int v,int e){
 26     ver[++tot]=v,Next[tot]=head[u],head[u]=tot,edge[tot]=e;
 27     ver[++tot]=u,Next[tot]=head[v],head[v]=tot,edge[tot]=0;
 28 }
 29 bool bfs(){
 30     while(!q.empty()) q.pop();
 31     for(int i=S;i<=T;++i) cur[i]=head[i];
 32     memset(dep,-1,sizeof(dep));
 33     q.push(S),dep[S]=0;
 34     while(!q.empty()){
 35         int u=q.front();q.pop();
 36         for(int i=head[u];i;i=Next[i]){
 37             int v=ver[i];
 38             if(dep[v]<0&&edge[i]){
 39                 dep[v]=dep[u]+1,q.push(v);
 40                 if(v==T) return true;
 41             }
 42         }
 43     }
 44     return false;
 45 }
 46 int dfs(int u,int limit){
 47     if(u==T||!limit) return limit;
 48     int flow=0,f;
 49     for(int i=cur[u];i;cur[u]=i=Next[i]){
 50         int v=ver[i];
 51         if(dep[v]==dep[u]+1&&(f=dfs(v,min(limit,edge[i])))){
 52             flow+=f,limit-=f;
 53             edge[i]-=f,edge[i^1]+=f;
 54             if(!limit) break;
 55         }
 56     }
 57     if(!flow) dep[u]=-1;
 58     return flow;
 59 }
 60 int dinic(){
 61     int flow=0;
 62     while(bfs()) flow+=dfs(S,inf);
 63     return flow;
 64 }
 65 void update(int &p,int x,int l,int r,int a,int b){
 66     p=++cnt;
 67     if(l==r){
 68         add(p+n,b,inf);
 69         if(x) add(p+n,x+n,inf);
 70         return;
 71     }
 72     int mid=l+r>>1;
 73     if(a<=mid) R[p]=R[x],update(L[p],L[x],l,mid,a,b);
 74     else L[p]=L[x],update(R[p],R[x],mid+1,r,a,b);
 75 }
 76 inline void getall(int x,int y){
 77     update(rt[x],rt[x],1,n,v[y],y);
 78     for(int i=0,s=ch[y].size();i<s;++i) getall(x,ch[y][i]);
 79 }
 80 void DFS(int u){
 81     sz[u]=1;
 82     for(int i=0,s=ch[u].size();i<s;++i){
 83         int v=ch[u][i];
 84         DFS(v),sz[u]+=sz[v];
 85         if(sz[v]>sz[son[u]]) son[u]=v;
 86     }
 87     update(rt[u],rt[son[u]],1,n,v[u],u);
 88     for(int i=0,s=ch[u].size();i<s;++i)
 89     if(ch[u][i]!=son[u]) getall(u,ch[u][i]);
 90 }
 91 void query(int p,int l,int r,int ql,int qr,int x){
 92     if(!p) return;
 93     if(ql<=l&&qr>=r) return (void)(add(x+n,p+n,inf));
 94     int mid=l+r>>1;
 95     if(ql<=mid) query(L[p],l,mid,ql,qr,x);
 96     if(qr>mid) query(R[p],mid+1,r,ql,qr,x);
 97 }
 98 int main(){
 99     //freopen("testdata.in","r",stdin);
100     n=read(),m=read();
101     for(int i=2;i<=n;++i) fa[i]=read(),ch[fa[i]].push_back(i);
102     for(int i=1;i<=n;++i) v[i]=read();
103     DFS(1);
104     S=0;
105     for(int i=1;i<=cnt;++i){
106         if(L[i]) add(i+n,L[i]+n,inf);
107         if(R[i]) add(i+n,R[i]+n,inf);
108     }
109     for(int i=1;i<=m;++i){
110         int l=read(),r=read(),p=read(),t=read();
111         add(S,(++cnt)+n,t);
112         query(rt[p],1,n,l,r,cnt);
113     }
114     T=cnt+n+1;
115     for(int i=1;i<=n;++i) add(i,T,1);
116     printf("%d\n",dinic());
117     return 0;
118 }

 

posted @ 2018-09-01 20:23  bztMinamoto  阅读(227)  评论(0编辑  收藏  举报
Live2D