zoukankan      html  css  js  c++  java
  • 牛客多校4

    J

    题意:给你一个hash表,让你给出一个字典序最小的输入。

    思路:按数字大小从小到大插入,用链表和bit维护过程。

    #include<bits/stdc++.h>
    #define LL long long
    #define fi first
    #define se second
    #define mk make_pair
    #define pii pair<int, int>
    #define y1 skldjfskldjg
    #define y2 skldfjsklejg
    
    using namespace std;
    
    const int N = 2e5 + 7;
    const int M = 1e5 + 7;
    const int inf = 0x3f3f3f3f;
    const LL INF = 0x3f3f3f3f3f3f3f3f;
    const int mod = 1e9 +7;
    
    int n, tot, all, ans[N], a[N], L[N], R[N];
    vector<pii> vec;
    struct node {
        int nx, pre, val;
    } b[N];
    
    struct BIT {
        int a[N];
        void init(int n) {
            for(int i = 0; i <= n; i++) a[i] = 0;
        }
        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;
        }
    } bit;
    
    void del(int u) {
        int to = b[u].nx;
        int from = b[u].pre;
        b[from].nx = b[u].nx;
        b[to].pre = b[u].pre;
    }
    
    bool is(int l, int r) {
        if(l == r) return true;
        if(l < r) return bit.sum(r) - bit.sum(l - 1) == (r - l);
        return bit.sum(r) + bit.sum(n) - bit.sum(l - 1) == (r + n - l);
    }
    
    void check(int u, int fa) {
        if(u == fa || b[u].val == -1 || !is(L[u], R[u])) return;
        int to = b[u].nx;
        ans[tot++] = b[u].val;
        bit.modify(u, 1);
        del(u);
        check(to, u);
    
    }
    int main() {
    
        int T; scanf("%d", &T);
        while(T--) {
            tot = 0; all = 0;
            vec.clear();
            scanf("%d", &n);
            bit.init(n);
            for(int i = 1; i <= n; i++) {
                scanf("%d", &a[i]);
                b[i].val = -1;
                b[i].nx = (i + 1 - 1) % n + 1;
                b[i].pre = (i - 1 - 1 + n) % n + 1;
                if(a[i] != -1) {
                    L[i] = a[i] % n + 1;
                    R[i] = i;
                    vec.push_back(mk(a[i], i));
                }
    
            }
            sort(vec.begin(), vec.end());
    
            for(int i = 0; i < vec.size(); i++) {
                int l = vec[i].fi % n + 1, r = vec[i].se;
                b[r].val = vec[i].fi;
                if(is(l, r)) {
                    check(r, -1);
                }
            }
    
            if(tot != vec.size()) {
                puts("-1");
            } else {
                if(tot == 0) {
                    puts("");
                } else {
                    printf("%d", ans[0]);
                    for(int i = 1; i < tot; i++) printf(" %d", ans[i]);
                    puts("");
                }
            }
        }
        return 0;
    }
    
    
    /*
    1
    10
    8 10 -1 -1 34 75 86 55 88 18
    */
    View Code

    线段树优化建边写法

    #include<bits/stdc++.h>
    #define LL long long
    #define fi first
    #define se second
    #define mk make_pair
    #define pii pair<int,int>
    #define pLL pair<long long, long long>
    #define piii pair<int, pair<int,int>>
    
    using namespace std;
    
    const int N = 2e5 + 7;
    const int M = 1e4 + 7;
    const int inf = 0x3f3f3f3f;
    const LL INF = 0x3f3f3f3f3f3f3f3f;
    const int mod = 1e9 + 7;
    const double eps = 1e-10;
    const double PI = acos(-1);
    
    int ans[N], a[N], id[N << 2], idx, sum, tot, n;
    vector<int> edge[N << 2];
    bool f[N << 2];
    struct node {
        int val, deg, id;
        bool operator < (const node &rhs) const {
            return val > rhs.val;
        }
    } p[N << 2];
    
    void build(int l, int r, int rt) {
        if(l == r) {
            id[rt] = l;
            edge[id[rt]].clear();
            p[id[rt]].deg = 0;
            p[id[rt]].val = a[l];
            p[id[rt]].id = l;
            if(a[l] < 0) f[rt] = true;
            else f[rt] = false;
            return;
        }
        id[rt] = idx++;
        edge[id[rt]].clear();
        p[id[rt]].deg = 0;
        p[id[rt]].val = -2;
        p[id[rt]].id = id[rt];
        int mid = l + r >> 1;
        build(l, mid, rt << 1);
        build(mid + 1, r, rt << 1 | 1);
        edge[id[rt << 1]].push_back(id[rt]);
        edge[id[rt << 1 | 1]].push_back(id[rt]);
        p[id[rt]].deg += 2;
        f[rt] = f[rt << 1] | f[rt << 1 | 1];
    }
    
    bool addEdge(int L, int R, int to, int l, int r, int rt) {
        if(l >= L && r <= R) {
            edge[id[rt]].push_back(to);
            p[to].deg++;
            return f[rt];
        }
        int mid = l + r >> 1;
        bool ans = false;
        if(L <= mid) ans |= addEdge(L, R, to, l, mid, rt << 1);
        if(R > mid) ans |= addEdge(L, R, to, mid + 1, r, rt << 1 | 1);
        return ans;
    }
    
    int main() {
        int T; scanf("%d", &T);
        while(T--) {
            scanf("%d", &n); idx = n; sum = 0;
            for(int i = 0; i < n; i++) {
                scanf("%d", &a[i]);
                if(a[i] != -1) sum++;
            }
    
            build(0, n - 1, 1);
    
            bool judge = false;
            for(int i = 0; i < n; i++) {
                if(a[i] == -1) continue;
                int l = a[i] % n, r = i;
                if(l < r) {
                    judge |= addEdge(l, r - 1, i, 0, n - 1, 1);
                } else if(l > r) {
                    if(r) judge |= addEdge(0, r - 1, i, 0, n - 1, 1);
                    judge |= addEdge(l, n - 1, i, 0, n - 1, 1);
                }
                if(judge) break;
            }
    
            if(judge) {
                puts("-1");
            } else {
                priority_queue<node> que; tot = 0;
                for(int i = 0; i < idx; i++)
                    if(p[i].deg == 0) que.push(p[i]);
    
                while(!que.empty()) {
                    node u = que.top(); que.pop();
                    if(u.val >= 0) ans[tot++] = u.val;
                    for(int i = 0; i < edge[u.id].size(); i++) {
                        int v = edge[u.id][i];
                        p[v].deg--;
                        if(!p[v].deg) que.push(p[v]);
                    }
                }
    
                if(tot < sum) {
                    puts("-1");
                } else {
                    if(!tot) puts("");
                    else {
                        printf("%d", ans[0]);
                        for(int i = 1; i < tot; i++) printf(" %d", ans[i]);
                        puts("");
                    }
                }
            }
        }
        return 0;
    }
    
    /*
    */
    View Code

    E

    题意:这个题意真的是看不懂。。  给你n个点,每个点都有一个出现概率,一个点会覆盖自己左下角的区域,

    问你期望的面积是多少。

    思路:很容易想到扫描线维护面积并,用线段树维护一下在未被覆盖的概率。

    #include<bits/stdc++.h>
    #define LL long long
    #define fi first
    #define se second
    #define mk make_pair
    #define pii pair<int, int>
    #define y1 skldjfskldjg
    #define y2 skldfjsklejg
    
    using namespace std;
    
    const int N = 1e5 + 7;
    const int M = 1e5 + 7;
    const int inf = 0x3f3f3f3f;
    const LL INF = 0x3f3f3f3f3f3f3f3f;
    const int mod = 1e9 +7;
    
    int n, hs[N], pos[N], tot;
    LL x[N], y[N], z[N], f[N], a[N << 2], lazy[N << 2];
    
    LL fastPow(LL a, LL b) {
        LL ans = 1;
        while(b) {
            if(b & 1) ans = ans * a % mod;
            a = a * a % mod; b >>= 1;
        }
        return ans;
    }
    
    void build(int l, int r, int rt) {
        lazy[rt] = 1;
        if(l == r) {
            a[rt] = hs[l + 1] - hs[l];
            return;
        }
        int mid = l + r >> 1;
        build(l, mid, rt << 1);
        build(mid + 1, r, rt << 1 | 1);
        a[rt] = (a[rt << 1] + a[rt << 1 | 1]) % mod;
    }
    
    void pushdown(int rt) {
        if(lazy[rt] == 1) return;
        lazy[rt << 1] = lazy[rt << 1] * lazy[rt] % mod;
        lazy[rt << 1 | 1] = lazy[rt << 1 | 1] * lazy[rt] % mod;
        a[rt << 1] = a[rt << 1] * lazy[rt] % mod;
        a[rt << 1 | 1] = a[rt << 1 | 1] * lazy[rt] % mod;
        lazy[rt] = 1;
    }
    
    void update(int L, int R, LL v, int l, int r, int rt) {
        if(l >= L && r <= R) {
            lazy[rt] = lazy[rt] * v % mod;
            a[rt] = a[rt] * v % mod;
            return;
        }
        int mid = l + r >> 1;
        pushdown(rt);
        if(L <= mid) update(L, R, v, l, mid, rt << 1);
        if(R > mid) update(L, R, v, mid + 1, r, rt << 1 | 1);
        a[rt] = (a[rt << 1] + a[rt << 1 | 1]) % mod;
    }
    
    LL query(int L, int R, int l, int r, int rt) {
        if(l >= L && r <= R) return a[rt];
        int mid = l + r >> 1; LL ans = 0;
        pushdown(rt);
        if(L <= mid) ans = query(L, R, l, mid, rt << 1);
        if(R > mid) ans = (ans + query(L, R, mid + 1, r, rt << 1 | 1)) % mod;
        return ans;
    }
    
    struct node {
        bool operator < (const node &rhs) const {
            return x < rhs.x;
        }
        int x, y;
        LL p;
    } qus[N];
    
    int main() {
        int T; scanf("%d", &T);
        while(T--) {
            tot = 0;
            scanf("%d", &n);
            for(int i = 1; i <= n; i++) {
                scanf("%d%d", &qus[i].x, &qus[i].y);
                scanf("%lld%lld", &x[i], &y[i]);
                f[i] = x[i] * fastPow(y[i], mod - 2) % mod;
                z[i] = (1 - f[i] + mod) % mod;
                hs[++tot] = qus[i].y;
            }
            hs[++tot] = 0;
            sort(hs + 1, hs + tot + 1);
            tot = unique(hs + 1, hs + tot + 1) - hs - 1;
            hs[tot + 1] = hs[tot];
            build(1, tot, 1);
    
            for(int i = 1; i <= n; i++) {
                qus[i].y = lower_bound(hs + 1, hs + tot + 1, qus[i].y) - hs;
                update(1, qus[i].y - 1, z[i], 1, tot, 1);
                qus[i].p = fastPow(z[i], mod - 2);
            }
    
            sort(qus + 1, qus + 1 + n);
            LL ans = 0; qus[0].x = 0;
    
            for(int i = 1; i <= n; i++) {
                LL lenx = qus[i].x - qus[i - 1].x;
                LL leny = (hs[tot] - a[1] + mod) % mod;
                ans += lenx * leny % mod;
                if(ans >= mod) ans -= mod;
                update(1, qus[i].y - 1, qus[i].p, 1, tot, 1);
            }
    
            printf("%lld
    ", ans);
        }
        return 0;
    }
    
    
    /*
    */
    View Code

    C

    数位dp

    #include<bits/stdc++.h>
    #define LL long long
    #define ll long long
    #define fi first
    #define se second
    #define mk make_pair
    #define pii pair<int, int>
    #define y1 skldjfskldjg
    #define y2 skldfjsklejg
    
    using namespace std;
    
    const int N = 1e5 + 7;
    const int M = 1e5 + 7;
    const int inf = 0x3f3f3f3f;
    const LL INF = 0x3f3f3f3f3f3f3f3f;
    const LL mod = 1e9 + 7;
    const int maxn = 1e5;
    
    int f[64][128][2], tot;
    LL n;
    int s[64];
    
    void add(int &a, int b) {
        a += b; if(a >= mod) a -= mod;
    }
    
    int dp(int pos, int p, bool fg, int cnt) {
        if(pos == -1) return p == -1 ? 0 : abs(cnt - 64);
        if(p != -1 && !fg && f[pos][cnt][p] != -1) return f[pos][cnt][p];
        int up = fg ? s[pos] : 1;
        int ret = 0;
        for(int i = 0; i <= up; i++) {
            if(p == -1) {
                if(!i) add(ret, dp(pos - 1, p, fg && i == up, cnt));
                else add(ret, dp(pos - 1, 1, fg && i == up, cnt));
            } else {
                add(ret, dp(pos - 1, i, fg && i == up, cnt + ((i == p) ? -1 : 1)));
            }
        }
        if(p != -1 && !fg) f[pos][cnt][p] = ret;
        return ret;
    }
    
    int main() {
        int T; scanf("%d", &T);
        memset(f, -1, sizeof(f));
        while(T--) {
            scanf("%lld", &n); tot = 0;
            while(n) {
                if(n & 1) s[tot++] = 1;
                else s[tot++] = 0;
                n >>= 1;
            }
            printf("%d
    ", dp(tot - 1, -1, 1, 64));
        }
        return 0;
    }
    
    /*
    10
    10
    */
    View Code
  • 相关阅读:
    创建共享内存函数CreateFileMapping()详解
    窗口类、窗口类对象与窗口
    ubuntu中文版切换为英文后字体变化问题解决
    安装ubuntu12.04LTS卡住以及花屏问题
    时钟周期、振荡周期、机器周期、CPU周期、状态周期、指令周期、总线周期、任务周期
    波特率
    myod
    mycp
    20165226 2017-2018-2《Java程序设计》课程总结
    2017-2018-2 20165226 实验五《网络编程与安全》实验报告
  • 原文地址:https://www.cnblogs.com/CJLHY/p/9385892.html
Copyright © 2011-2022 走看看