zoukankan      html  css  js  c++  java
  • Codeforces 513D2 Constrained Tree

    Constrained Tree

    没写出来好菜啊啊。

    首先根据输入我们能算出某些节点的左儿子的范围, 右儿子的范围(此时并不准确)

    然后我们在划分u这个节点的时候我们从左右开始用树状数组check每一个点是否可行, 即这个点没有被覆盖,

    因为左右同时开始所以复杂度是nlognlogn,以前做过这种从两头开始check的。

    还有一种方法用线段树, 从n - > 1取更新每个点的准确范围,然后直接输出答案。

    还有一种方法是dfs的过程中, 先给所子树划分一个区域, 这个区域可能是不对的,然后递归左子树, 能到正确的区域才去递归右子树。

    #include<bits/stdc++.h>
    #define LL long long
    #define LD long double
    #define ull unsigned long long
    #define fi first
    #define se second
    #define mk make_pair
    #define PLL pair<LL, LL>
    #define PLI pair<LL, int>
    #define PII pair<int, int>
    #define SZ(x) ((int)x.size())
    #define ALL(x) (x).begin(), (x).end()
    #define fio ios::sync_with_stdio(false); cin.tie(0);
    using namespace std;
    
    const int N = 1e6 + 7;
    const int inf = 0x3f3f3f3f;
    const LL INF = 0x3f3f3f3f3f3f3f3f;
    const int mod = 1e9 + 7;
    const double eps = 1e-8;
    const double PI = acos(-1);
    
    template<class T, class S> inline void add(T& a, S b) {a += b; if(a >= mod) a -= mod;}
    template<class T, class S> inline void sub(T& a, S b) {a -= b; if(a < 0) a += mod;}
    template<class T, class S> inline bool chkmax(T& a, S b) {return a < b ? a = b, true : false;}
    template<class T, class S> inline bool chkmin(T& a, S b) {return a > b ? a = b, true : false;}
    
    struct Bit {
        int a[N];
        void modify(int x, int v) {
            for(int i = x; i < N; i += i & -i)
                a[i] += v;
        }
        int sum(int x) {
            int ans = 0;
            for(int i = x; i; i -= i & -i)
                ans += a[i];
            return ans;
        }
    };
    
    int n, m;
    char s[10];
    vector<PII> vc[N];
    vector<int> ans;
    Bit bit;
    
    void dfs(int l, int r) {
        if(l > r) return;
        if(l == r) {
            ans.push_back(l);
            return;
        }
        int L = l, R = r;
        for(auto& t : vc[l]) {
            if(t.se) chkmin(R, t.fi - 1);
            else chkmax(L, t.fi);
            bit.modify(l, -1);
            bit.modify(t.fi, 1);
        }
        for( ; L <= R; L++, R--) {
            if(!bit.sum(L)) {
                dfs(l + 1, L);
                ans.push_back(l);
                dfs(L + 1, r);
                return;
            }
            if(!bit.sum(R)) {
                dfs(l + 1,  R);
                ans.push_back(l);
                dfs(R + 1, r);
                return;
            }
        }
        puts("IMPOSSIBLE");
        exit(0);
    }
    
    int main() {
        scanf("%d%d", &n, &m);
        for(int i = 1; i <= m; i++) {
            int a, b;
            scanf("%d%d%s", &a, &b, s);
            if(b <= a) {
                puts("IMPOSSIBLE");
                return 0;
            }
            if(s[0] == 'L') vc[a].push_back(mk(b, 0));
            else vc[a].push_back(mk(b, 1));
            bit.modify(a, 1);
            bit.modify(b, -1);
        }
        dfs(1, n);
        for(auto& t : ans) printf("%d ", t);
        puts("");
        return 0;
    }
    
    /*
    */
  • 相关阅读:
    tracert命令与tracert (IP地址)-d有什么区别?
    linux下通过进程名查看其占用端口
    Union和Union All的区别
    外连接、内连接
    Linux 删除文件夹和文件的命令(强制删除包括非空文件)
    linux查看当前目录
    Linux chmod命令及权限含义
    MySQL的if,case语句
    case when
    java生成验证码图片
  • 原文地址:https://www.cnblogs.com/CJLHY/p/10735316.html
Copyright © 2011-2022 走看看