zoukankan      html  css  js  c++  java
  • 【考试总结2021-02-24】执行

    A.gift

    考虑交换次数是置换的阶 (-1),那么答案就是 (n-) 环数

    考虑把已知的连通块表示一下,链首和链尾可能分别是 (0 o id,id o 0,0 o 0,id o id)

    已经是环的部分直接统计答案

    求出来这几种情况的方案是 (trivial) 的,这个直接做就行

    这四种环需要合并,可以用 (0 o 0) 来作为 (id o 0,0 o id) 的媒介,(id o id) 的部分会在 $0 o 0 $ 中出现

    (f_i)(i) 个环的方案数,(g_i) 是至少 (i) 个环的

    钦定 (j) 个形成 (i) 个环,剩下的随便连,得到式子

    (g_i=sum_{j=i}^n inom n jegin{bmatrix}i\ jend {bmatrix} A(n+m-j,n-j))

    二项式反演得到

    [f(n)=sum_{i=n}^m inom i n g(i)Leftrightarrow g(n)=sum_{i=n}^m (-1) ^{i-n} inom i n f(i) ]

    [f_i=sum_{j=i}^ninom nj egin{bmatrix} i\ j end{bmatrix}frac{(n+m-j-1)!}{(m-1)!} ]

    那么分别对 $c_{0,id},c_{id,0} $ 作为多项式的次数进行卷积即可

    B.girls

    先容斥,答案为不考虑互斥减掉至少一个互斥的,再减掉两个互斥的,加上图上三元环的带权贡献

    貌似分开计数就行了,图上三元环计数的方法是按照出度排序,原图中的边,小的点向大的点连边

    枚举 (1 o n),先标记出点,再在出点的出点里面找被标记点就行了

    #include <bits/stdc++.h>
    using namespace std;
    #define ull unsigned long long
    #define int long long
    #define For(i,a,b) for(register int i=a;i<=b;++i)
    #define Down(i,a,b) for(register int i=a;i>=b;i--)
    #define reg register
    inline int min(int x, int y) {
        return x < y ? x : y;
    }
    inline int max(int x, int y) {
        return x > y ? x : y;
    }
    inline void swap(int &x, int &y) {
        int t = x;
        x = y;
        y = t;
        return ;
    }
    namespace yspm {
    inline int read() {
        int res = 0, f = 1;
        char k;
    
        while (!isdigit(k = getchar()))
            if (k == '-')
                f = -1;
    
        while (isdigit(k))
            res = res * 10 + k - '0', k = getchar();
    
        return res * f;
    }
    const int N = 2e5 + 10;
    int head[N], cnt, n, m, id[N], q[N], deg[N];
    vector<int>f[N], g[N];
    ull A, B, C, ans;
    bool vis[N];
    struct node {
        int to, nxt;
    } e[N << 1];
    inline bool cmp(int x, int y) {
        return deg[x] > deg[y];
    }
    inline void add(int u, int v) {
        e[++cnt].nxt = head[u];
        e[head[u] = cnt].to = v;
        deg[u]++;
        f[u].push_back(v);
        return ;
    }
    signed main() {
        //      freopen("1.in","r",stdin);
        n = read();
        m = read();
        A = read(), B = read(), C = read();
    
        for (reg int i = 1, u, v; i <= m; ++i)
            u = read(), v = read(), add(u, v), add(v, u);
    
        for (reg int i = 0; i < n; ++i) {
            sort(f[i].begin(), f[i].end());
    
            if (i + 2 < n)
                ans += A * ((n - i - 2) * (n - i - 1) / 2) * i;
    
            if (i + 1 < n)
                ans += (i * (n - i - 1)) * B * i;
    
            if (i - 2 >= 0)
                ans += (i - 1) * i / 2 * C * i;
        }
    
        for (reg int x = 0; x < n; ++x)
            for (reg int i = head[x]; i; i = e[i].nxt) {
                int t = e[i].to;
    
                if (t < x)
                    continue;
    
                ans -= (n - 1 - t) * (x * A + t * B) + C * ((n - 1) * n / 2 - (t + 1) * t / 2);
                ans -= (t - x - 1) * (x * A + t * C) + B * (t * (t - 1) / 2 - (x + 1) * x / 2);
                ans -= x * (x * B + t * C) + A * x * (x - 1) / 2;
            }
    
        for (reg int x = 0; x < n; ++x) {
            ull sum = 0, c = 0;
    
            for (reg int i = head[x]; i; i = e[i].nxt)
                if (e[i].to > x)
                    sum += e[i].to, ++c;
    
            for (reg int i = head[x]; i; i = e[i].nxt)
                if (e[i].to < x)
                    ans += e[i].to * A * c + x * B * c + sum * C;
    
            c = 0;
            sum = 0;
    
            for (reg int j = ((int)f[x].size()) - 1; j >= 0 && f[x][j] > x; --j)
                ans += x * A * c + f[x][j] * B * c + sum * C, sum += f[x][j], ++c;
    
            sum = 0;
            c = 0;
    
            for (reg int i = 0; i < f[x].size() && f[x][i] < x; ++i)
                ans += sum * A + f[x][i] * B * c + x * C * c, sum += f[x][i], ++c;
        }
    
        for (reg int i = 0; i < n; ++i)
            q[i] = i;
    
        sort(q, q + n, cmp);
    
        for (reg int i = 0; i < n; ++i)
            id[q[i]] = i;
    
        For(x, 0, n - 1) for (reg int i = head[x]; i; i = e[i].nxt)
            if (id[e[i].to] > id[x])
                g[x].push_back(e[i].to);
    
        For(i, 0, n - 1) {
            int now = q[i];
    
            for (auto p : g[now])
                vis[p] = 1;
    
            for (auto t : g[now])
                for (auto z : g[t]) {
                    if (!vis[z])
                        continue;
    
                    int fir = now, sec = t, thi = z;
    
                    if (sec < fir)
                        swap(sec, fir);
    
                    if (thi < fir)
                        swap(thi, fir);
    
                    if (thi < sec)
                        swap(sec, thi);
    
                    ans -= sec * B + fir * A + thi * C;
                }
    
            for (auto p : g[now])
                vis[p] = 0;
        }
        printf("%lld
    ", ans);
        return 0;
    }
    }
    signed main() {
        return yspm::main();
    }
    
    

    C.string

    题目中的要求都是广义 (sam) 的基操

    写个支持链加的 (lct) 每个点上维护 (20) 个串的 (endpos) 信息

    对于版本,开 (n)(vector) 记一下每个串最后一次被修改,查的时候 (upper\_bound-1)

    剩下的就是写了

  • 相关阅读:
    关于jquery判断对象是否为空
    php设计模式学习之观察者模式
    php设计模式学习之单例模式
    Nginx+phpfastcgi下flush输出问题
    php设计模式学习之工厂模式
    centos设置ssh免密码登陆
    关于yii2自带验证码功能不显示问题
    html原样输出html代码
    centos7安装iptables
    centos下配置nginx支持php
  • 原文地址:https://www.cnblogs.com/yspm/p/14444890.html
Copyright © 2011-2022 走看看