• LibreOJ NOI Round #2 Day 1


    LibreOJ NOI Round #2 Day 1 

    T1:

    别被定义弄晕了

    反着做,A->1/A+B

    取倒数没法做,所以变成a/b,维护2*2的矩阵

    区间?不用线段树,不用倍增

    存在逆矩阵,直接前缀积

    注意左乘右乘方向

    T2

    模拟费用流

     

    经典老鼠和洞的问题

    序列:从左往右扫,

    到了老鼠i,wi加入堆,

    到了洞j,找权值最大的未匹配老鼠或者已经匹配的洞k,如果valk+vj>0,更新ans,pop,然后把-vj加入堆

    外向树:可并堆进行上述操作

     

    而本题带修

    (52)60pts做法:

    https://www.luogu.org/blog/i207M/libreoj-noi-round-2-xie-ti-bao-gao

    相当于模拟动态加边费用流,

    建图方式就是树上直接建,S到miner,gold到T

    加入一个miner,会和匹配的miner、未匹配的gold产生匹配

    疯狂DFS走有流量的边到这些点,选择最大的

    加入gold,和未匹配的miner、匹配的gold产生匹配

    这里DFS,如果反向边有流量才走,因为实际在反向增广

    如果有匹配并且贡献>0,暴力把整个路径流量改变

    匹配和未匹配的miner和gold用2个堆维护

    由于可能加入的费用过大,会造成正环

    一般机械费用流要消正环

    但是其实无所谓,正环只会产生在miner-S-miner之间,以及gold-T-gold之间

    和我们的人工方法一致

    #include<bits/stdc++.h>
    #define reg register int
    #define il inline
    #define fi first
    #define se second
    #define mk(a,b) make_pair(a,b)
    #define numb (ch^'0')
    #define pb push_back
    #define solid const auto &
    #define enter cout<<endl
    #define pii pair<int,int>
    using namespace std;
    typedef long long ll;
    template<class T>il void rd(T &x){
        char ch;x=0;bool fl=false;while(!isdigit(ch=getchar()))(ch=='-')&&(fl=true);
        for(x=numb;isdigit(ch=getchar());x=x*10+numb);(fl==true)&&(x=-x);}
    template<class T>il void output(T x){if(x/10)output(x/10);putchar(x%10+'0');}
    template<class T>il void ot(T x){if(x<0) putchar('-'),x=-x;output(x);putchar(' ');}
    template<class T>il void prt(T a[],int st,int nd){for(reg i=st;i<=nd;++i) ot(a[i]);putchar('
    ');}
    namespace Modulo{
    const int mod=998244353;
    il int ad(int x,int y){return x+y>=mod?x+y-mod:x+y;}
    il int sub(int x,int y){return ad(x,mod-y);}
    il int mul(int x,int y){return (ll)x*y%mod;}
    il void inc(int &x,int y){x=ad(x,y);}
    il void inc2(int &x,int y){x=mul(x,y);}
    il int qm(int x,int y=mod-2){int ret=1;while(y){if(y&1) ret=mul(x,ret);x=mul(x,x);y>>=1;}return ret;}
    template<class ...Args>il int ad(const int a,const int b,const Args &...args) {return ad(ad(a,b),args...);}
    template<class ...Args>il int mul(const int a,const int b,const Args &...args) {return mul(mul(a,b),args...);}
    }
    //using namespace Modulo;
    namespace Miracle{
    const int N=100000+5;
    const int inf=0x3f3f3f3f;
    int n,m;
    ll ans;
    priority_queue<ll>q[N][2];
    //0: matched miner ; no match gold
    //1: matched gold  ; no match miner
    struct node{
        int nxt,to;
        int w,c;
    }e[2*N];
    int du[N];
    int hd[N],cnt=1;
    void add(int x,int y,int w,int c){
        e[++cnt].nxt=hd[x];
        e[cnt].to=y;e[cnt].w=w;e[cnt].c=c;    
        hd[x]=cnt;
        
        e[++cnt].nxt=hd[y];
        e[cnt].to=x;e[cnt].w=0;e[cnt].c=-c;
        hd[y]=cnt;
    }
    int pre[N]; 
    ll mx;
    int id;
    void dfs(int x,int fa,ll d,int tp){
        if(!q[x][tp].empty()){
            if(q[x][tp].top()+d>mx){
                mx=q[x][tp].top()+d;
                id=x;
            }
        }
        for(reg i=hd[x];i;i=e[i].nxt){
            int y=e[i].to;
            if(y==fa) continue;
            
            if(tp==0){
                if(e[i].w) pre[y]=i,dfs(y,x,d+e[i].c,tp);
            }else{
                if(e[i^1].w) pre[y]=i,dfs(y,x,d+e[i^1].c,tp);
            }
        }
    }
    void wrk(int x,int v,int tp){
        mx=1ll*-0x3f3f3f3f3f3f3f3f,id=0;
        dfs(x,0,0,tp);
        
        if(mx+v>0){
            ans+=mx+v;
            ll val=q[id][tp].top();
            q[id][tp].pop();
            q[id][tp^1].push(-val);
            
            q[x][tp].push(-v);
            if(tp==0){
                while(id!=x){
                    e[pre[id]].w--;
                    e[pre[id]^1].w++;
                    id=e[pre[id]^1].to;
                }
            }else{
                while(id!=x){
                    e[pre[id]].w++;
                    e[pre[id]^1].w--;
                    id=e[pre[id]^1].to;
                }
            }
        }else{
            q[x][tp^1].push(v);
        }
    }
    int main(){
        rd(n);rd(m);
        int x,y,z;
        for(reg i=1;i<n;++i){
            rd(x);rd(y);rd(z);
            add(x,y,inf,z);
            ++du[y];
        }
       // int rt=0;
        //for(reg i=1;i<=n;++i){if(du[i]==0) rt=i;}
        
        int op,v;
        while(m--){
            rd(op);rd(x);rd(v);
            --op;
            wrk(x,v,op);
            printf("%lld
    ",ans);
        }
        return 0;
    }
    
    }
    signed main(){
        Miracle::main();
        return 0;
    }
    
    /*
       Author: *Miracle*
    */
    View Code

    100pts:

    miner往上跳到最高点,子树最大值就是答案

    gold就是到根的链的所有轻儿子连通块内的最大值

    树剖维护一下,找连通块,线段树pushup时候考虑中间边有没有,就好了

    在写了在写了

    T3:

    好题

    https://loj.ac/article/1779

    没有大于号限制是好算的.

    容斥的话,枚举i最后连续的不满足的大于号

    分治NTT

    dp0=1.题解打错了

  • 相关阅读:
    【Problem】前端项目运行:Module build failed:Error Node Sass does not yet support my current environmen
    element ui源码解析 -- Pagination篇( 副:列表页进入详情页再返回后,如何保持当前页码正确 )
    vue mixins是什么及应用
    bootstrap fileinput实现限制图片上传数量及如何控制分批多次上传
    fileinput 配置项大全,从源码中翻出了很多属性,没那么多时间一一验证,特发出来给大家参考参考
    provide inject应用及和props对比
    element ui源码解析 -- input篇
    vue指令应用--实现输入框常见过滤功能
    vue项目实现导出数据到excel
    组件绑定v-model,实现最大化复用
  • 原文地址:https://www.cnblogs.com/Miracevin/p/11148295.html
Copyright © 2020-2023  润新知