• bzoj 4383: [POI2015]Pustynia


    复习了一下线段树优化建图的姿势,在线段树上连边跑拓扑排序

    这题竟然卡vector……丧病

    #include <bits/stdc++.h>
    #define N 1810000
    using namespace std;
    int s, n, m;
    int pi[N], vis[N];
    int lt[N], nt[N], bi[N], ci[N];
    int lp[N], np[N], bp[N];
    int tl;
    int lb[N], rb[N], lc[N], rc[N];
    int out[N], intr[N];
    int Q[N], fr, bc;
    inline void build(int a, int b, int c)
    {
        nt[++ tl] = lt[a]; lt[a] = tl; bi[tl] = b; ci[tl] = c;
        np[tl] = lp[b]; lp[b] = tl; bp[tl] = a; out[a] ++;
        /*
        bi[a].push_back(b);
        bp[b].push_back(a);
        ci[a].push_back(c);
        */
        //printf("%d %d %d
    ", a, b, c);
    }
    int tot;
    void dfs_build(int t, int l, int r, int x)
    {
        if (l > r) return;
        if (l <= lb[t] && rb[t] <= r) {build(x, t, 0); return;}
        if (l <= rb[lc[t]]) dfs_build(lc[t], l, r, x);
        if (r >= lb[rc[t]]) dfs_build(rc[t], l, r, x);
    }
    int build_tree(int l, int r)
    {
        int t = ++ tot;
        lb[t] = l; rb[t] = r;
        if (l != r)
        {
            lc[t] = build_tree(l, (l + r) / 2); 
            rc[t] = build_tree((l + r) / 2 + 1, r);
            build(t, lc[t], 0);
            build(t, rc[t], 0);
        }
        else intr[l] = t;
        return t;
    }
    
    inline int read()
    {
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    
    int main()
    {
        n = read(); s = read(); m = read();
        build_tree(1, n);
        for (int i = 1; i <= s; ++ i)
        {
            int p, d;
            p = read(); d = read();
            pi[intr[p]] = d;
        }
         
        //return 0;
        for (int i = 1; i <= m; ++ i)
        {
            int l, r, k;
            l = read(); r = read(); k = read();
             
            for (int j = 1, p = l - 1; j <= k + 1; ++ j)
            {
                int a;
                if (j <= k)
                {
                    a = read();
                    build(intr[a], tot + i, 1);
                }
                else a = r + 1;
                if ((a - 1) - (p + 1) <= 10)
                {
                    for (int q = p + 1; q < a; ++ q)
                        build(tot + i, intr[q], 0);
                }
                else 
                    dfs_build(1, p + 1, a - 1, tot + i);
                p = a;
            }
        }
        for (int i = 1; i <= m + tot; ++ i)
            if (!out[i]) Q[bc ++] = i;
        
        while (fr != bc)
        {
            int hd = Q[fr ++]; vis[hd] = 1;
            int mx = 1;
            for (int i = lt[hd]; i; i = nt[i])
                mx = max(mx, pi[bi[i]] + ci[i]);
            if (!pi[hd])
            {
                if (mx > 1000000000)
                {
                    puts("NIE");
                    return 0;
                }
                pi[hd] = mx;
            }
            else if (mx > pi[hd])
            {
                puts("NIE");
                return 0;
            }
            
            for (int i = lp[hd]; i; i = np[i])
            {
                out[bp[i]] --;
                if (!out[bp[i]])
                    Q[bc ++] = bp[i];
            }
        }
        for (int i = 1; i <= m + tot; ++ i)
            if (!vis[i]) {puts("NIE"); return 0;}
        puts("TAK");
        for (int i = 1; i <= n; ++ i) printf("%d ", pi[intr[i]]);
    }

    话说是不是在主席树上也可以干一样的事情呢(手动斜眼

  • 相关阅读:
    linux 清空文件内容命令
    优秀的java 社区
    vue强制刷新组件 ----组件重置到初始状态
    function的json对象转换字符串与字符串转换为对象的方法
    js实现深度优先遍历和广度优先遍历
    Egg.js中使用sequelize事务
    JavaScript ES6 数组新方法 学习随笔
    eggjs的参数校验模块egg-validate的使用和进一步定制化升级
    Node.js 服务端图片处理利器
    webp图片实践之路
  • 原文地址:https://www.cnblogs.com/AwD-/p/6287613.html
Copyright © 2020-2023  润新知