• BZOJ 3681 线段树合并+网络流


    思路:

    暴力建图有n*m条边 

    考虑怎么优化

    (那就只能加个线段树了呗)

    然后我就不会写了.....

    抄了一波题解

    //By SiriusRen
    #include <bits/stdc++.h>
    using namespace std;
    const int N=10050,M=N*100,inf=0x3f3f3f3f;
    vector<int>vec[N];
    int n,m,first[M],next[M],v[M],w[M],tot,cnt=2,S=1,T=2;
    int lson[M],rson[M],root[N],jy,vis[M];
    int read(){
        char p=getchar();int x=0;
        while(p<'0'||p>'9')p=getchar();
        while(p>='0'&&p<='9')x=x*10+p-'0',p=getchar();
        return x;
    }
    void Add(int x,int y,int z){v[tot]=y,w[tot]=z,next[tot]=first[x],first[x]=tot++;}
    void add(int x,int y,int z){Add(x,y,z),Add(y,x,0);}
    int insert(int l,int r,int pos,int num){
        pos=++cnt;
        if(l==r){add(cnt,T,1);return pos;}
        int mid=(l+r)>>1;
        if(mid<num)add(pos,rson[pos]=insert(mid+1,r,rson[pos],num),inf);
        else add(pos,lson[pos]=insert(l,mid,lson[pos],num),inf);
        return pos;
    }
    int merge(int l,int r,int pos,int last){
        if(pos*last==0)return pos+last;
        int now=++cnt,mid=(l+r)>>1;
        if(l==r){add(now,pos,inf),add(now,last,inf);return now;}
        add(now,lson[now]=merge(l,mid,lson[pos],lson[last]),inf);
        add(now,rson[now]=merge(mid+1,r,rson[pos],rson[last]),inf);
        return now;
    }
    void dfs(int x){
        for(int i=0;i<vec[x].size();i++)
            dfs(vec[x][i]),root[x]=merge(1,n,root[x],root[vec[x][i]]);
    }
    void query(int l,int r,int pos,int L,int R){
        if(!pos)return;
        if(l>=L&&r<=R){add(cnt,pos,inf);return;}
        int mid=(l+r)>>1;
        if(mid<L)query(mid+1,r,rson[pos],L,R);
        else if(mid>=R)query(l,mid,lson[pos],L,R);
        else query(l,mid,lson[pos],L,R),query(mid+1,r,rson[pos],L,R);
    }
    bool tell(){
        memset(vis,-1,sizeof(vis));
        queue<int>q;q.push(S),vis[S]=0;
        while(!q.empty()){
            int t=q.front();q.pop();
            for(int i=first[t];~i;i=next[i])
                if(vis[v[i]]==-1&&w[i])vis[v[i]]=vis[t]+1,q.push(v[i]);
        }return ~vis[T];
    }
    int zeng(int x,int y){
        if(x==T)return y;
        int r=0;
        for(int i=first[x];~i;i=next[i])if(vis[v[i]]==vis[x]+1&&w[i]){
            int t=zeng(v[i],min(w[i],y-r));
            w[i]-=t,w[i^1]+=t,r+=t;
        }if(!r)vis[x]=-1;
        return r;
    }
    int flow(){int ans=0;while(tell())while(jy=zeng(S,inf))ans+=jy;return ans;}
    int main(){
        memset(first,-1,sizeof(first));
        scanf("%d%d",&n,&m);
        for(int i=2;i<=n;i++)vec[read()].push_back(i);
        for(int i=1;i<=n;i++)root[i]=insert(1,n,root[i],read());
        dfs(1);
        for(int i=1;i<=m;i++){
            int l=read(),r=read(),x=read(),y=read();
            cnt++,add(S,cnt,y),query(1,n,root[x],l,r);
        }
        printf("%d
    ",flow());
    }
    
  • 相关阅读:
    idea开发工具关于svn上代码的颜色
    写一个Request包装类ExternalApiHttpServletRequestWrapper(外部接口请求使用用于解密)
    什么情况下,需要用事务?
    SpringBoot 2.1.6.RELEASE ->SpringCloudAlibaba
    oracle查看锁表进程,杀掉锁表进程
    JavaScript 闭包
    萤石云定时更新 accessToken
    Ubuntu Linux的DevExpressReport无法显示报表(.net core)
    Vue在IE下打开空白解决方案
    DFT scan chain 介绍
  • 原文地址:https://www.cnblogs.com/SiriusRen/p/6637688.html
Copyright © 2020-2023  润新知