zoukankan      html  css  js  c++  java
  • 牛客练习赛26

    C 城市规划

    ps:想复杂了,记录每个点靠的最近的左端点和枚举到这个点时,上次切割的位置。(每次切割都切右端点

    namespace fastIO {
        #define BUF_SIZE 100000
        bool IOerror = 0;
        inline char nc() {
            static char buf[BUF_SIZE], *p1 = buf + BUF_SIZE, *pend = buf + BUF_SIZE;
            if(p1 == pend) {
                p1 = buf;
                pend = buf + fread(buf, 1, BUF_SIZE, stdin);
                if(pend == p1) {
                    IOerror = 1;
                    return -1;
                }
            }
            return *p1++;
        }
        inline bool blank(char ch) {
            return ch == ' ' || ch == '
    ' || ch == '
    ' || ch == '	';
        }
        inline void read(int &x) {
            char ch;
            while(blank(ch = nc()));
            if(IOerror) return;
            for(x = ch - '0'; (ch = nc()) >= '0' && ch <= '9'; x = x * 10 + ch - '0');
        }
        #undef BUF_SIZE
    };
    using namespace fastIO;
    
    const int N = 1000005;
    
    int n, m;
    int a[N];
    
    int main()
    {
        read(n);
        read(m);
        int l, r;
        Rep(i, 1, m) {
            read(l);
            read(r);
            if (a[r] < l) a[r] = l;
        }
    
        int ans = 0, cut = a[1];
        Rep(i, 1, n) if (a[i]) {
            if (a[i] >= cut) {
                ans++;
                cut = i;
            }
        }
        pr(ans);
        return 0;
    }

    D XOR序列

     ps:x ^ ? = y,则 ? = x ^ y。所以问题转化为:这n个数的线性基能否表示出 ?。

    int n, q;
    LL p[100];
    
    void Insert(int x) {
        for (int i = 62; ~i; --i) if ((1 << i) & x) {
            if (!p[i]) {
                p[i] = x;
                break;
            }
            x ^= p[i];
        }
    }
    
    bool check(int x) {
        for (int i = 62; ~i; --i) if ((x & (1 << i)) && p[i]) {
            x ^= p[i];
        }
        return (x == 0);
    }
    
    int main()
    {
        sc(n);
        Rep(i, 1, n) {
            int x;
            sc(x);
            Insert(x);
        }
        sc(q);
        while(q--) {
            int x, y;
            sc(x), sc(y);
            if (check(x ^ y)) puts("YES");
            else puts("NO");
        }
        return 0;
    }

     树上路径

    ps:设最短路径上的点的和为a,点的平方和为b,则 ans = (a * a — b) / 2。然后 a^2 和 b 分别用树剖+线段树维护就行了。注意取模 !!!!!!!!

    const int N = 100005;
    const int mod = 1000000007;
    const int inv2 = 500000004;
    
    int n, m;
    int v[N], dep[N], pa[N], id[N], rk[N], sz[N], son[N], top[N];
    
    
    struct BST {
        int cnt;
        int a[N * 4], b[N * 4], use[4 * N];
    
        void Inite() {
            cnt = 0;
            mem(use, 0);
        }
        void Pushup(int root) {
            a[root] = (0ll + a[lson] + a[rson]) % mod;
            b[root] = (0ll + b[lson] + b[rson]) % mod;
        }
        void Pushdown(int l, int r, int root) {
            use[lson] = (0ll + use[lson] + use[root]) % mod;
            use[rson] = (0ll + use[rson] + use[root]) % mod;
            int mid = (l + r) >> 1;
            b[lson] = (0ll + b[lson] + 1ll * use[root] * use[root] % mod * (mid - l + 1) % mod + 2ll * use[root] * a[lson] % mod) % mod;
            b[rson] = (0ll + b[rson] + 1ll * use[root] * use[root] % mod * (r - mid) % mod + 2ll * use[root] * a[rson] % mod) % mod;
            a[lson] = (0ll + a[lson] + 1ll * (mid - l + 1) * use[root] % mod) % mod;
            a[rson] = (0ll + a[rson] + 1ll * (r - mid) * use[root] % mod) % mod;
            use[root] = 0;
        }
        void Build(int l, int r, int root) {
            if (l == r) {
                a[root] = v[rk[++cnt]];
                b[root] = 1ll * a[root] * a[root] % mod;
                return;
            }
            int mid = (l + r) >> 1;
            Build(l, mid, lson);
            Build(mid + 1, r, rson);
            Pushup(root);
        }
        void Update(int l, int r, int root, int L, int R, int x) {
            if (l > R || r < L) return;
            if (L <= l && r <= R) {
                use[root] = (0ll + use[root] + x) % mod;
                b[root] = (0ll + b[root] + 1ll * x * x % mod * (r - l + 1) % mod + 2ll * x * a[root] % mod) % mod;
                a[root] = (0ll + a[root] + 1ll * x * (r - l + 1) % mod) % mod;
                return;
            }
            int mid = (l + r) >> 1;
            if (use[root]) Pushdown(l, r, root);
            Update(l, mid, lson, L, R, x);
            Update(mid + 1, r, rson, L, R, x);
            Pushup(root);
        }
        int Query(int l, int r, int root, int L, int R, bool flag) {
            if (l > R || r < L) return 0;
            if (L <= l && r <= R) {
                if (flag) return a[root];
                else return b[root];
            }
            if (use[root]) Pushdown(l, r, root);
            int mid = (l + r) >> 1;
            int ans = 0;
            ans = (0ll + ans + Query(l, mid, lson, L, R, flag)) % mod;
            ans = (0ll + ans + Query(mid + 1, r, rson, L, R, flag)) % mod;
            return ans;
        }
    };
    
    BST T;
    
    struct TreeCut {
        int cnt;
        vector<int> G[N];
    
        void Inite() {
            T.Inite();
    
            cnt = 0;
            mem(son, -1);
            Rep(i, 0, n) G[i].clear();
        }
        void addedge(int u, int v) {
            G[u].pb(v);
            G[v].pb(u);
        }
        void DFS1(int u, int p, int d) {
            pa[u] = p;
            sz[u] = 1;
            dep[u] = d;
            for (auto v : G[u]) if (v != p) {
                DFS1(v, u, d + 1);
                sz[u] += sz[v];
                if (son[u] == -1 || sz[son[u]] < sz[v]) son[u] = v;
            }
        }
        void DFS2(int u, int st) {
            top[u] = st;
            id[u] = ++cnt;
            rk[cnt] = u;
            if (son[u] == -1) return;
            DFS2(son[u], st);
            for (auto v : G[u]) if (v != son[u] && v != pa[u]) DFS2(v, v);
        }
    
        void Start() {
            DFS1(1, 1, 0);
            DFS2(1, 1);
    
            T.Inite();
            T.Build(1, n, 1);
        }
        void Update(int u, int v, int x) {
            int pu = top[u], pv = top[v];
            while(pu != pv) {
                if (dep[pu] > dep[pv]) {
                    T.Update(1, n, 1, id[pu], id[u], x);
                    u = pa[pu];
                }
                else {
                    T.Update(1, n, 1, id[pv], id[v], x);
                    v = pa[pv];
                }
                pu = top[u], pv = top[v];
            }
            if (id[u] <= id[v]) T.Update(1, n, 1, id[u], id[v], x);
            else T.Update(1, n, 1, id[v], id[u], x);
        }
        int sum(int u, int v) {
            int pu = top[u], pv = top[v];
    
            int sa = 0, sb = 0;
            while(pu != pv) {
                if (dep[pu] > dep[pv]) {
                    sa = (0ll + sa + T.Query(1, n, 1, id[pu], id[u], 1)) % mod;
                    sb = (0ll + sb + T.Query(1, n, 1, id[pu], id[u], 0)) % mod;
                    u = pa[pu];
                }
                else {
                    sa = (0ll + sa + T.Query(1, n, 1, id[pv], id[v], 1)) % mod;
                    sb = (0ll + sb + T.Query(1, n, 1, id[pv], id[v], 0)) % mod;
                    v = pa[pv];
                }
                pu = top[u], pv = top[v];
            }
            if (id[u] <= id[v]) {
                sa = (0ll + sa + T.Query(1, n, 1, id[u], id[v], 1)) % mod;
                sb = (0ll + sb + T.Query(1, n, 1, id[u], id[v], 0)) % mod;
            }
            else {
                sa = (0ll + sa + T.Query(1, n, 1, id[v], id[u], 1)) % mod;
                sb = (0ll + sb + T.Query(1, n, 1, id[v], id[u], 0)) % mod;
            }
            return (1ll * sa * sa % mod - 1ll * sb + mod) * (LL)inv2 % mod;
        }
    };
    
    TreeCut cut;
    
    int main()
    {
        sc(n), sc(m);
        Rep(i, 1, n) sc(v[i]);
    
        cut.Inite();
        rep(i, 1, n) {
            int u, v;
            sc(u), sc(v);
            cut.addedge(u, v);
        }
    
        cut.Start();
        while(m--) {
            int op, x, y, z;
            sc(op);
            if (op == 1) {
                sc(x), sc(z);
                T.Update(1, n, 1, id[x], id[x] + sz[x] - 1, z);
            }
            else if (op == 2) {
                sc(x), sc(y), sc(z);
                cut.Update(x, y, z);
            }
            else {
                sc(x), sc(y);
                pr(cut.sum(x, y));
            }
        }
        return 0;
    }
  • 相关阅读:
    asp.net 2.0教程 其它服务器控件
    asp.net 2.0教程 个性化用户配置
    asp.net 2.0教程 数据绑定控件
    asp.net 2.0教程 主题和皮肤
    asp.net 2.0教程 网站导航控件
    asp.net 2.0教程 数据缓存
    asp.net 2.0教程 数据源控件
    理解Windows会话
    SlickEdit 编辑器中的王者
    Mark Lucovsky NT内核作者之一
  • 原文地址:https://www.cnblogs.com/zgglj-com/p/9638311.html
Copyright © 2011-2022 走看看