bzoj 3681 Arietta

题目大意:

一棵树上每个点有权值,m次操作 每次可以在$d_i$的节点的子树中选择$t_i$个$l_i \le val \le r_i$的点

求这么多次操作后最多选多少个点(每个点只能被选一次

思路:

暴力建图非常显然

$S \rightarrow New (val=t)\rightarrow (x \in {[l,r]∩tree_d}) \rightarrow T$

优化边数的时候可以使用$dsu\space on\space  tree$即对于点$x$的子树,可以继承重儿子然后对于不在这条重链上的点暴力加入

使用主席树来实现(需要注意

对于整棵树建完主席树后再加入操作的边

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<cstdlib>
  5 #include<cmath>
  6 #include<algorithm>
  7 #include<queue>
  8 #include<vector>
  9 #include<map>
 10 #include<set>
 11 #define ll long long
 12 #define inf 2139062143
 13 #define MAXN 10100
 14 #define DMAXN 551000
 15 #define DMAXM 1000100
 16 #define MOD 998244353
 17 #define rep(i,s,t) for(register int i=(s),i##__end=(t);i<=i##__end;++i)
 18 #define dwn(i,s,t) for(register int i=(s),i##__end=(t);i>=i##__end;--i)
 19 #define ren for(register int i=fst[x];i;i=nxt[i])
 20 #define pb(i,x) vec[i].push_back(x)
 21 #define pls(a,b) (a+b)%MOD
 22 #define mns(a,b) (a-b+MOD)%MOD
 23 #define mul(a,b) (1LL*(a)*(b))%MOD
 24 using namespace std;
 25 inline int read()
 26 {
 27     int x=0,f=1;char ch=getchar();
 28     while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
 29     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
 30     return x*f;
 31 }
 32 int n,m,S,T,fst[MAXN],nxt[MAXN],to[MAXN];
 33 namespace D
 34 {
 35     int fst[DMAXN],nxt[DMAXM<<1],to[DMAXM<<1],val[DMAXM<<1],cnt;
 36     int q[DMAXN],l,r,vis[DMAXN],tot,dis[DMAXN],cur[DMAXM<<1];
 37     void mem() {memset(fst,0,sizeof(fst));cnt=1;}
 38     void add(int u,int v,int w) {nxt[++cnt]=fst[u],fst[u]=cnt,to[cnt]=v,val[cnt]=w;}
 39     void ins(int u,int v,int w) {add(u,v,w);add(v,u,0);}
 40     int bfs()
 41     {
 42         vis[T]=++tot,q[l=r=1]=T,dis[T]=0;int x;
 43         while(l<=r)
 44         {
 45             x=q[l++];ren if(vis[to[i]]!=tot&&val[i^1])
 46                 vis[to[i]]=tot,dis[to[i]]=dis[x]+1,q[++r]=to[i];
 47         }
 48         return vis[S]==tot;
 49     }
 50     int dfs(int x,int a)
 51     {
 52         if(!a||x==T) return a;int f,flw=0;
 53         for(int &i=cur[x];i&&a;i=nxt[i])
 54             if(dis[to[i]]==dis[x]-1&&val[i]&&(f=dfs(to[i],min(a,val[i]))))
 55                 val[i]-=f,val[i^1]+=f,flw+=f,a-=f;
 56         return flw;
 57     }
 58     int solve(int sum)
 59     {
 60         int f,ans=0;while(bfs()) 
 61             {rep(i,0,sum) cur[i]=fst[i];while(f=dfs(S,inf)) ans+=f;}
 62         return ans;
 63     }
 64 };
 65 int fa[MAXN],sz[MAXN],hvs[MAXN],cnt,tot,val[MAXN],rt[MAXN],ls[MAXN*60],rs[MAXN*60];
 66 void add(int u,int v) {nxt[++cnt]=fst[u],fst[u]=cnt,to[cnt]=v;}
 67 void mdf(int &k,int kk,int l,int r,int a,int t)
 68 {
 69     k=++tot,ls[k]=ls[kk],rs[k]=rs[kk];
 70     if(l==r){D::ins(k+n,t,inf);if(kk) D::ins(k+n,kk+n,inf);return ;}int mid=l+r>>1;
 71     if(a<=mid) mdf(ls[k],ls[kk],l,mid,a,t);
 72     else mdf(rs[k],rs[kk],mid+1,r,a,t);
 73 }
 74 void query(int k,int l,int r,int a,int b,int x)
 75 {
 76     if(!k) return ;if(l==a&&r==b) {D::ins(tot+n,k+n,x);return ;}
 77     int mid=l+r>>1;
 78     if(b<=mid) query(ls[k],l,mid,a,b,x);
 79     else if(a>mid) query(rs[k],mid+1,r,a,b,x);
 80     else {query(ls[k],l,mid,a,mid,x);query(rs[k],mid+1,r,mid+1,b,x);}
 81 }
 82 void Get(int x,int anc)
 83 {
 84     mdf(rt[anc],rt[anc],1,n,val[x],x);
 85     ren Get(to[i],anc);
 86 }
 87 void dfs(int x)
 88 {
 89     sz[x]=1;ren
 90     {
 91         dfs(to[i]),sz[x]+=sz[to[i]];
 92         if(sz[to[i]]>sz[hvs[x]]) hvs[x]=to[i];
 93     }
 94     mdf(rt[x],rt[hvs[x]],1,n,val[x],x);
 95     ren if(to[i]^hvs[x]) Get(to[i],x);
 96 }
 97 int main()
 98 {
 99     n=read(),m=read();int a,b,c,d;D::mem();
100     rep(i,2,n) fa[i]=read(),add(fa[i],i);rep(i,1,n) val[i]=read();dfs(1);
101     rep(i,1,tot) {if(ls[i]) D::ins(i+n,ls[i]+n,inf);if(rs[i]) D::ins(i+n,rs[i]+n,inf);}
102     S=0,T=n+tot+1;
103     rep(i,1,n) D::ins(i,T,1);tot++;
104     while(m--)
105     {
106         a=read(),b=read(),c=read(),d=read(),tot++;D::ins(S,tot+n,d);
107         query(rt[c],1,n,a,b,d);
108     }
109     printf("%d\n",D::solve(tot+n));
110 }
View Code

 

posted @ 2019-03-12 11:19  jack_yyc  阅读(158)  评论(0编辑  收藏  举报