zoukankan      html  css  js  c++  java
  • 【AtCoder】ARC102 题解

    C - Triangular Relationship

    题解

    枚举一个数%K的值然后统计另两个

    代码

    #include <bits/stdc++.h>
    #define enter putchar('
    ')
    #define space putchar(' ')
    #define pii pair<int,int>
    #define fi first
    #define se second
    #define MAXN 200005
    #define pb push_back
    //#define ivorysi
    using namespace std;
    typedef long long int64;
    typedef double db;
    template<class T>
    void read(T &res) {
        res = 0;T f = 1;char c = getchar();
        while(c < '0' || c > '9') {
            if(c == '-') f = -1;
            c = getchar();
        }
        while(c >= '0' && c <= '9') {
            res = res * 10 + c - '0';
            c = getchar();
        }
        res *= f;
    }
    template<class T>
    void out(T x) {
        if(x < 0) {x = -x;putchar('-');}
        if(x >= 10) out(x / 10);
        putchar('0' + x % 10);
    }
    int N,K;
    int cnt[200005];
    int main() {
    #ifdef ivorysi
        freopen("f1.in","r",stdin);
    #endif
        read(N);read(K);
        int64 ans = 0;
        for(int i = 1 ; i <= N ; ++i) {
            cnt[i % K]++;
        }
        for(int i = 0 ; i < K ; ++i) {
            if((K - i) * 2 % K == 0) {
                ans += 1LL * cnt[i] * cnt[(K - i) % K] * cnt[(K - i) % K];
            }
        }
        out(ans);enter;
        return 0;
    }
    

    D - All Your Paths are Different Lengths

    题解

    感觉自己万分智障,没切掉,被学弟吊着打呀qwq

    我们连出一条边全为(2^0)(2^(r - 1))的链出来,(2^r)是L的最高位
    然后我们通过增加一些点到N的边权X,使得数量为L且合法即可。。

    代码

    #include <bits/stdc++.h>
    #define enter putchar('
    ')
    #define space putchar(' ')
    #define pii pair<int,int>
    #define fi first
    #define se second
    #define mp make_pair
    #define pb push_back
    #define eps 1e-8
    //#define ivorysi
    using namespace std;
    typedef long long int64;
    typedef double db;
    template<class T>
    void read(T &res) {
        res = 0;T f = 1;char c = getchar();
        while(c < '0' || c > '9') {
            if(c == '-') f = -1;
            c = getchar();
        }
        while(c >= '0' && c <= '9') {
            res = res * 10 - '0' + c;
            c = getchar();
        }
        res *= f;
    }
    template<class T>
    void out(T x) {
        if(x < 0) {x = -x;putchar('-');}
        if(x >= 10) out(x / 10);
        putchar('0' + x % 10);
    }
    int L,N;
    void add(int u,int v,int c) {
        out(u);space;out(v);space;out(c);enter;
    }
    int main() {
    #ifdef ivorysi
    	freopen("f1.in","r",stdin);
    #endif
        read(L);
        int r;
        for(r = 20 ; r >= 0 ; --r) {
            if(L & (1 << r)) break;
        }
        N = r + 1;out(N);space;int M = r * 2 + __builtin_popcount(L) - 1;out(M);enter;
        for(int i = 1 ; i <= N - 1 ; ++i) {
            add(i,i + 1,(1 << i - 1));add(i,i + 1,0);
        }
        for(int i = 1 ; i <= N - 1 ; ++i) {
            if(L & (1 << i - 1)) {
                L ^= (1 << i - 1);
                add(i,N,L);
            }
        }
    }
    

    E - Stop. Otherwise...

    题解

    计数题

    加和的限制相当于有几个数两个中只能出现一个
    算一个dp[i][j]表示把i个数分成j段,每一段两种染色方式染色的方案数

    然后枚举有多少数用来给两种方式染色,有多少数给怎么放都没事的数

    如果有出现两次就不合法的数,那么就先算不存在它的排列,再算存在它一个的排列

    代码

    #include <bits/stdc++.h>
    #define enter putchar('
    ')
    #define space putchar(' ')
    #define pii pair<int,int>
    #define fi first
    #define se second
    #define mp make_pair
    #define MAXN 1000005
    #define mo 999999137
    #define pb push_back
    //#define ivorysi
    using namespace std;
    typedef long long int64;
    typedef double db;
    template<class T>
    void read(T &res) {
        res = 0;T f = 1;char c = getchar();
        while(c < '0' || c > '9') {
            if(c == '-') f = -1;
            c = getchar();
        }
        while(c >= '0' && c <= '9') {
            res = res * 10 + c - '0';
            c = getchar();
        }
        res *= f;
    }
    template<class T>
    void out(T x) {
        if(x < 0) {x = -x;putchar('-');}
        if(x >= 10) out(x / 10);
        putchar('0' + x % 10);
    }
    const int MOD = 998244353;
    int fac[4005],inv[4005],invfac[4005],N,K,vis[4005],pw[4005];
    int dp[4005][4005];
    int mul(int a,int b) {
        return 1LL * a * b % MOD;
    }
    int inc(int a,int b) {
        return a + b >= MOD ? a + b - MOD : a + b;
    }
    int C(int n,int m) {
        if(n < m) return 0;
        if(n < 0 || m < 0) return 0;
        return mul(fac[n],mul(invfac[m],invfac[n - m]));
    }
    int fpow(int x,int c) {
        int res = 1,t = x;
        while(c) {
            if(c & 1) res = mul(res,t);
            t = mul(t,t);
            c >>= 1;
        }
        return res;
    }
    int main() {
    #ifdef ivorysi
        freopen("f1.in","r",stdin);
    #endif
        inv[1] = 1;pw[0] = 1;
        for(int i = 2 ; i <= 4000 ; ++i) {
            inv[i] = mul(inv[MOD % i],MOD - MOD / i);
        }
        fac[0] = invfac[0] = 1;
        for(int i = 1 ; i <= 4000 ; ++i) {
            fac[i] = mul(fac[i - 1],i);invfac[i] = mul(invfac[i - 1],inv[i]);
            pw[i] = mul(pw[i - 1],2);
        }
        read(K);read(N);
        dp[0][1] = 1;
        for(int i = 1 ; i <= N ; ++i) dp[i][1] = 2;
        dp[0][0] = 1;
        for(int j = 2 ; j <= K ; ++j) {
            int s = 1;
            dp[0][j] = 1;
            for(int i = 1 ; i <= N ; ++i) {
                dp[i][j] = inc(mul(s,2),dp[i][j - 1]);
                s = inc(s,dp[i][j - 1]);
            }
        }
        for(int i = 2 ; i <= 2 * K ; ++i) {
            int cnt = 0,t = 0,rest = 0;
            memset(vis,0,sizeof(vis));
            for(int j = 1 ; j <= K ; ++j) {
                if(!vis[j] && j != i - j && i - j >= 1 && i - j <= K) {vis[j] = vis[i - j] = 1;++cnt;}
            }
            if(i % 2 == 0) ++t;
            rest = K - cnt * 2 - t;
            int ans = 0;
            for(int j = N ; j >= 0 ; --j) {
                ans = inc(ans,mul(dp[j][cnt],rest ? C(N - j - 1 + rest,rest - 1) : (N - j == 0)));
            }
            if(t) {
                for(int j = N - 1; j >= 0 ; --j) {
                    ans = inc(ans,mul(dp[j][cnt],rest ? C(N - 2 - j + rest,rest - 1) : (N - 1 - j == 0)));
                }
            }
            out(ans);enter;
        }
        return 0;
    }
    

    F - Revenge of BBuBBBlesort!

    题解

    我们按照逆操作考虑,容易发现是1-N顺序排列
    每次交换(a_{i - 1} < a_{i} < a_{i + 1})使得它变成排列p
    这样原始排列每次交换的时候相邻两个不会都进行操作,所以排列p如果合法的话一定是
    p[i] != i p[i + 1] == i + 1 p[i + 2] != i + 2....这样的排列

    所以我们只要对p排列,顺序找出区间l,r保证l + 1,l + 3...r - 1是固定不动的
    然后找出剩下往左往右的点,保证往左的点是顺序的,往右的点是顺序的即可

    代码

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <algorithm>
    #define enter putchar('
    ')
    #define space putchar(' ')
    #define fi first
    #define se second
    #define MAXN 300005
    //#define ivorysi
    #define pii pair<int,int>
    using namespace std;
    typedef long long int64;
    template<class T>
    void read(T &res) {
        res = 0;char c = getchar();T f = 1;
        while(c < '0' || c > '9') {
        	if(c == '-') f = -1;
        	c = getchar();
        }
        while(c >= '0' && c <= '9') {
        	res = res * 10 + c - '0';
        	c = getchar();
        }
        res *= f;
    }
     
    template<class T>
    void out(T x) {
        if(x < 0) {putchar('-');x = -x;}
        if(x >= 10) out(x / 10);
        putchar('0' + x % 10);
    }
    int N;
    int p[MAXN],v[MAXN],cnt,id[MAXN],dir[MAXN];
    bool vis[MAXN];
    void Solve() {
        read(N);
        for(int i = 1 ; i <= N ; ++i) read(p[i]);
        int la = 1;
        while(1) {
            while(p[la] == la && la <= N) ++la;
            if(la > N) break;
            int ed = la;
            while(1) {
                if(ed <= N && ((ed - la) & 1) && p[ed] == ed) ++ed;
                else if(ed <= N && !((ed - la) & 1) && p[ed] != ed) ++ed;
                else break;
            }
            --ed;
            if(p[ed] == ed) --ed;
            if(ed == la) {puts("No");return;}
            cnt = 0;
            for(int i = la ; i <= ed ; ++i) v[++cnt] = p[i];
            sort(v + 1,v + cnt + 1);
            for(int i = 1 ; i <= cnt ; ++i) {
                if(v[i] != i + la - 1) {puts("No");return;}
            }
            cnt = 0;
            for(int i = la ; i <= ed ; i += 2) {
                v[++cnt] = p[i];
                id[p[i]] = cnt;
            }
            sort(v + 1,v + cnt + 1);
            for(int i = la ; i <= ed ; i += 2) {
                int t = lower_bound(v + 1,v + cnt + 1,p[i]) - v;
                if(t <= id[p[i]]) dir[i] = 0;
                else dir[i] = 1;
            }
            int L = 0,R = 0;
            for(int i = la ; i <= ed ; i += 2) {
                if(dir[i] == 0) {
                    if(p[i] < L) {puts("No");return;}
                    L = p[i];
                }
                else {
                    if(p[i] < R) {puts("No");return;}
                    R = p[i];
                }
            }
            la = ed + 1;
        }
        puts("Yes");
    }
    int main() {
    #ifdef ivorysi
        freopen("f1.in","r",stdin);
    #endif
        Solve();
        return 0;
    }
    
  • 相关阅读:
    放置消息
    MQ基础概念和介绍
    jQuery之双下拉框
    Spring整合JMS——事务管理
    DataTable学习笔记---排序细则、列隐藏
    jquery datatables api
    JavaScript高级 面向对象(2)--调试工具的使用:音乐循环播放
    JavaScript高级 面向对象(1)--添加一个div标签
    VBA学习笔记(9)--生成点拨(1)
    VBA学习笔记(8)--遍历所有文件夹和文件
  • 原文地址:https://www.cnblogs.com/ivorysi/p/9696574.html
Copyright © 2011-2022 走看看