• 校赛部分题解


    校赛部分题解

    ps: 某毒瘤出题人的题解

    A,第一集,这是怎么肥死嘛

    统计字母签到题

    #include <bits/stdc++.h>
    
    using namespace std;
    const int MAXN = 1e5 + 10;
    
    int t, n;
    
    char str[MAXN];
    
    int cnt[10];
    
    int main()
    {
        map<char, int>mp;
        
        //hello world
    
        mp['h'] = 1; // 1
        mp['e'] = 2; // 1
        mp['l'] = 3; // 3
        mp['o'] = 4; // 2
        mp['w'] = 5; // 1
        mp['r'] = 6; // 1
        mp['d'] = 7; // 1
    
        scanf("%d", &t);
        while(t--) {
            
            scanf("%s", str);
            n = strlen(str);
    
            memset(cnt, 0, sizeof(cnt));
    
            for(int i = 0; i < n; i++ ) {
                if(mp.count(str[i])) {
                    cnt[ mp[str[i]] ]++;
                }
            }
    
            cnt[ mp['l'] ] /= 3;
            cnt[ mp['o'] ] /= 2;
    
            int ans = 0x3f3f3f3f;
            for(int i = 1; i <= 7; i++ ) {
                ans = min(ans, cnt[i]);
            }
    
            printf("%d
    ", ans);
    
        }
    
    
        return 0;
    }
    
    /**
    3
    helloworld
    helloworldooooooooooo
    helloworldhelloworldasjdkl
    */
    

    I, 第五集,不要007,要睡觉

    类似题: HDU 5950,我随手改了递推式

    这么裸的矩阵快速幂 F[n] = 2 * f[n - 1] + 3 * f[n - 2] + 3 * n^5 , 除了那个n^5。

    第一项,第二项直接输出答案

    当 n >= 3 时, 我们假设

    [A_n=left[ egin{matrix} F[n] & F[n-1] & n^5 & n^4 & n^3 & n^2 & n^1 & n^0\ 0 & 0 & 0 & 0 & 0 & 0 &0 &0 \ 0 & 0 & 0 & 0 & 0 & 0 &0 &0 \ 0 & 0 & 0 & 0 & 0 & 0 &0 &0 \ 0 & 0 & 0 & 0 & 0 & 0 &0 &0 \ 0 & 0 & 0 & 0 & 0 & 0 &0 &0 \ 0 & 0 & 0 & 0 & 0 & 0 &0 &0 \ 0 & 0 & 0 & 0 & 0 & 0 &0 &0 \ end{matrix} ight] ]

    [A_{n+1}=left[ egin{matrix} F[n+1] & F[n] & (n+1)^5 & (n+1)^4 & (n+1)^3 & (n+1)^2 & n+1 & 1\ 0 & 0 & 0 & 0 & 0 & 0 &0 &0 \ 0 & 0 & 0 & 0 & 0 & 0 &0 &0 \ 0 & 0 & 0 & 0 & 0 & 0 &0 &0 \ 0 & 0 & 0 & 0 & 0 & 0 &0 &0 \ 0 & 0 & 0 & 0 & 0 & 0 &0 &0 \ 0 & 0 & 0 & 0 & 0 & 0 &0 &0 \ 0 & 0 & 0 & 0 & 0 & 0 &0 &0 \ end{matrix} ight] ]

    假设一个矩阵B, 我们需要算一个B使得

    [A_{n+1} = A_n * B ]

    按照矩阵乘法规则易得

    [B=left[ egin{matrix} 2 & 1 & 0 & 0 & 0 & 0 & 0 & 0\ 3 & 0 & 0 & 0 & 0 & 0 &0 &0 \ 3 & 0 & 1 & 0 & 0 & 0 &0 &0 \ 0 & 0 & 5 & 1 & 0 & 0 &0 &0 \ 0 & 0 & 10 & 4 & 1 & 0 &0 &0 \ 0 & 0 & 10 & 6 & 3 & 1 &0 &0 \ 0 & 0 & 5 & 4 & 3 & 2 &1 &0 \ 0 & 0 & 1 & 1 & 1 & 1 &1 &1 \ end{matrix} ight] ]

    所以我们假设

    [A = left[ egin{matrix} b & a & 3^5 & 3^4 & 3^3 & 3^2 & 3^1 & 3^0\ 0 & 0 & 0 & 0 & 0 & 0 &0 &0 \ 0 & 0 & 0 & 0 & 0 & 0 &0 &0 \ 0 & 0 & 0 & 0 & 0 & 0 &0 &0 \ 0 & 0 & 0 & 0 & 0 & 0 &0 &0 \ 0 & 0 & 0 & 0 & 0 & 0 &0 &0 \ 0 & 0 & 0 & 0 & 0 & 0 &0 &0 \ 0 & 0 & 0 & 0 & 0 & 0 &0 &0 \ end{matrix} ight] ]

    [B = left[ egin{matrix} 2 & 1 & 0 & 0 & 0 & 0 & 0 & 0\ 3 & 0 & 0 & 0 & 0 & 0 &0 &0 \ 3 & 0 & 1 & 0 & 0 & 0 &0 &0 \ 0 & 0 & 5 & 1 & 0 & 0 &0 &0 \ 0 & 0 & 10 & 4 & 1 & 0 &0 &0 \ 0 & 0 & 10 & 6 & 3 & 1 &0 &0 \ 0 & 0 & 5 & 4 & 3 & 2 &1 &0 \ 0 & 0 & 1 & 1 & 1 & 1 &1 &1 \ end{matrix} ight] ]

    令矩阵 C = A * B ^ (n - 2), 答案为C[0][0]

    标称

    #include <bits/stdc++.h>
    
    using namespace std;
    const int MAXN = 110;
    typedef long long LL;
    const LL MOD = 2147493647;
    #define mod(x) ((x)%MOD)
    
    int n = 8;
    
    struct Mat {
        LL m[MAXN][MAXN];
        void init() {
            memset(m, 0, sizeof(m));
        }
        void set() {
            init();
            for(int i = 0; i < MAXN; i++ ) {
                m[i][i] = 1;
            }
        }
        void disp() {
            for(int i = 0; i < n; i++ ) {
                for(int j = 0; j < n; j++ ) {
                    printf("%-10d", m[i][j]);
                }
                puts("");
            }
        }
    } unit;
    
    Mat operator * (const Mat &a, const Mat &b) {
        Mat ret;
        ret.init();
        LL x = 0;
        for(int i = 0; i < n; i++ ) {
            for(int j = 0; j < n; j++ ) {
                x = 0;
                for(int k = 0; k < n; k++ ) {
                    x += mod((a.m[i][k] % MOD) * (b.m[k][j] % MOD));
                    x = mod(x);
                }
                ret.m[i][j] = mod(x);
            }
        }
        return ret;
    }
    
    Mat pow_mod(Mat a, LL n) {
        Mat ret = unit;
        while(n) {
            if(n & 1) {
                ret = ret * a;
            }
            a = a * a;
            n >>= 1;
        }
        return ret;
    }
    
    LL pow_mod(LL a, LL b) {
        LL res = 1;
        while(b) {
            if(b & 1) {
                res = (res * a) % MOD;
            } 
            b >>= 1;
            a = (a * a) % MOD;
        }
        return res;
    }
    
    int T;
    
    LL N, a, b;
    
    int map_b[8][8] = 
    {
        2, 1, 0, 0, 0, 0, 0, 0,
        3, 0, 0, 0, 0, 0, 0, 0,
        3, 0, 1, 0, 0, 0, 0, 0,
        0, 0, 5, 1, 0, 0, 0, 0,
        0, 0,10, 4, 1, 0, 0, 0,
        0, 0,10, 6, 3, 1, 0, 0,
        0, 0, 5, 4, 3, 2, 1, 0,
        0, 0, 1, 1, 1, 1, 1, 1
    };
    
    LL solve_check()
    {
        if(N == 1) {
            //printf("%lld
    ", a);
            return a;
        }
        if(N == 2) {
            //printf("%lld
    ", b);
            return b;
        }
        LL c = 0;
        vector<LL>v;
        v.push_back(0);
        v.push_back(a);
        v.push_back(b);
        for(int i = 3; i <= N; i++ ) {
            LL va = v[i - 1] * 2;
            va %= MOD;
            va += v[i - 2] * 3;
            va %= MOD;
            va += 3 * pow_mod(i, 5);
            va %= MOD;
            v.push_back(va);       
        }
        return v[N];
    }
    
    LL solve_std()
    {
        if(N == 1) {
            //printf("%lld
    ", a);
            return a;
        }
        if(N == 2) {
            //printf("%lld
    ", b);
            return b;
        }
        Mat A, B;
        A.init();
        B.init();
    
        A.m[0][0] = b;
        A.m[0][1] = a;
        A.m[0][2] = 3 * 3 * 3 * 3 * 3;
        A.m[0][3] = 3 * 3 * 3 * 3;
        A.m[0][4] = 3 * 3 * 3;
        A.m[0][5] = 3 * 3;
        A.m[0][6] = 3;
        A.m[0][7] = 1;
    
        for(int i = 0; i < 8; i++ ) {
            for(int j = 0; j < 8; j++ ) {
                B.m[i][j] = map_b[i][j];
            }
        }
        Mat res = A * pow_mod(B, N - 2);
        return res.m[0][0] % MOD;
    }
    
    void judge_std()
    {
        freopen("data.in", "w", stdout);
    
        srand(static_cast<unsigned int>(time(0)));
        
        LL MAX = (1LL << 31);
    
        int cas = 1000;
    
        printf("%d
    ", cas);
    
        for(int i = 1; i <= cas; i++ ) {
            N = rand() % MAX + 1;
            a = rand() % MAX + 1;
            b = rand() % MAX + 1;
            
            printf("%lld %lld %lld
    ", N, a, b);
    
            continue;
    
            LL ans1 = solve_std();
            LL ans2 = solve_check();
            if(ans1 != ans2) {
                puts(ans1 == ans2 ? "Yes" : "No");
                printf("cas = %d %lld %lld %lld
    ", i, N, a, b);
                printf("%lld %lld
    ", ans1, ans2);
                puts("error");
                return ;
            }
        }
        //puts("Accept");
    }
    
    int main()
    {
    
      //  freopen("data.in", "r", stdin);
      //  freopen("data.out", "w", stdout);
    
        unit.set();
    
        //judge_std();
    
    
        scanf("%d", &T);
        while(T--) {
            scanf("%lld %lld %lld", &N, &a, &b);
            printf("%lld
    ", solve_std());
        }
        return 0;
    }
    

    L, 第八集,我要是不呢?

    类似题: BZOJ 2400 SPOJ839

    前置技能网络流最小割

    异或运算中二进制位之间没有影响。我们可以把每一位单独处理。

    那么对于某一个二进制位。变成了取0和取1,不同就会对答案有贡献,对于边权的贡献最少?

    下面我们只针对二进制某一位。

    那么我们可以看成两种决策,一种把点归成0, 另一种归为1,那么点的两种决策就会造成贡献,我们要让它最小。就变成二选一的最小割模型了。

    我们对原图的边,建立双向边,权为1。对于某一位已知01的点,分别划分两个集合,一个连源点,一个汇点,权无穷大。那么我们求该图的最小割。就会在割掉某些边,使得点属于某一个集合,0集合或者1集合。我们要的边权最小也符合最小割的定义。最后我们跑最大流即可。然后在吧每一位的答案整合。

    #include <bits/stdc++.h>
    
    using namespace std;
    const int MAX_N = 555;
    const int MAX_M = 3050 * 2;
    
    int n, m, k;
    
    struct Edge {
        int u, v;
    } edge[MAX_M];
    
    int p[MAX_N], v[MAX_N];
    
    int vis[MAX_N];
    
    struct Dinic {
    
        static const int MAXN = 500 + 7;
        static const int MAXM = MAXN * MAXN;
        static const int INF = 0x3f3f3f3f;
    
        int n, m, s, t;
    
        int first[MAXN], cur[MAXN], dist[MAXN], sign;
    
        struct Node {
            int to, flow, next;
        } edge[MAXM * 4];
    
        inline void init(int start, int vertex, int ss, int tt) {
            n = vertex, s = ss, t = tt;
            for(int i = start; i <= n; i++ ) {
                first[i] = -1;
            }
            sign = 0;
        }
    
        inline void addEdge(int u, int v, int flow) {
            edge[sign].to = v, edge[sign].flow = flow, edge[sign].next = first[u];
            first[u] = sign++;
        }
    
        inline void add_edge(int u, int v, int flow) {
            addEdge(u, v, flow);
            addEdge(v, u, 0);
        }
    
        inline int dinic() {
            int max_flow = 0;
            while(bfs(s, t)) {
                for(int i = 0; i <= n; i++ ) {
                    cur[i] = first[i];
                }
                max_flow += dfs(s, INF);
            }
            return max_flow;
        }
    
        bool bfs(int s, int t) {
            memset(dist, -1, sizeof(dist));
            queue<int>que;
            que.push(s), dist[s] = 0;
            while(!que.empty()) {
                int now = que.front();
                que.pop();
                if(now == t) {
                    return 1;
                }
                for(int i = first[now]; ~i; i = edge[i].next) {
                    int to = edge[i].to, flow = edge[i].flow;
                    if(dist[to] == -1 && flow > 0) {
                        dist[to] = dist[now] + 1;
                        que.push(to);
                    }
                }
            }
            return 0;
        }
    
        int dfs(int now, int max_flow) {
            if(now == t) {
                return max_flow;
            }
            int ans = 0, next_flow = 0;
            for(int &i = cur[now]; ~i; i = edge[i].next) {
                int to = edge[i].to, flow = edge[i].flow;
                if(dist[to] == dist[now] + 1 && flow > 0) {
                    next_flow = dfs(to, min(max_flow - ans, flow));
                    ans += next_flow;
                    edge[i].flow -= next_flow;
                    edge[i ^ 1].flow += next_flow;
                    if(ans == max_flow) {
                        return max_flow;
                    }
                }
            }
            if(ans == 0) {
                return dist[now] = 0;
            }
            return ans;
        }
    
        void find_set_s(int x) {
            vis[x] = 1;
            for(int i = first[x]; ~i; i = edge[i].next) {
                int to = edge[i].to, flow = edge[i].flow;
                if(!vis[to] && flow) {
                    find_set_s(to);
                }
            }
        }
    } cwl;
    
    int ans[MAX_N];
    
    int main() {
    
        int t;
        scanf("%d", &t);
        while(t--) {
            scanf("%d %d", &n, &m);
            for(int i = 1; i <= m; i++ ) {
                scanf("%d %d", &edge[i].u, &edge[i].v);
            }
            scanf("%d", &k);
            for(int i = 1; i <= k; i++ ) {
                scanf("%d %d", &p[i], &v[i]);
            }
            memset(ans, 0, sizeof(ans));
            for(int bit = 0; bit < 31; bit++ ) {
                cwl.init(0, n + 1, 0, n + 1);
                for(int i = 1; i <= m; i++ ) {
                    int u = edge[i].u, v = edge[i].v;
                    cwl.add_edge(u, v, 1);
                    cwl.add_edge(v, u, 1);
                }
                for(int i = 1; i <= k; i++ ) {
                    if((v[i] >> bit) & 1) {
                        cwl.add_edge(0, p[i], cwl.INF);
                    } else {
                        cwl.add_edge(p[i], n + 1, cwl.INF);
                    }
                }
                cwl.dinic();
                memset(vis, 0, sizeof(vis));
                cwl.find_set_s(0);
                for(int i = 1; i <= n; i++ ) {
                    if(vis[i]) {
                        ans[i] += (1 << bit);
                    }
                }
            }
            //for(int i = 1; i <= n; i++ ) {
            //    printf("data = %d
    ", ans[i]);
            //}
            long long res = 0;
            for(int i = 1; i <= m; i++ ) {
                res += ans[ edge[i].u ] ^ ans[ edge[i].v ];
            }
            printf("%lld
    ", res);
        }
    
        return 0;
    }
    
  • 相关阅读:
    .net 使用 swagger 操作
    oracle 基础
    关于webapi跨域问题的一些坑坑
    sqlHelper
    微博数据接入开发
    mvc后台上传
    sql server 报错处理
    asp.net 微信开发(二)
    收集一些关于OI/ACM的奇怪的东西……
    LeetCode 229 Majority Element II
  • 原文地址:https://www.cnblogs.com/Q1143316492/p/10854507.html
Copyright © 2020-2023  润新知