zoukankan      html  css  js  c++  java
  • Educational Codeforces Round 84 (Rated for Div. 2)

    Educational Codeforces Round 84 (Rated for Div. 2)

    D: Infinite Path

    【题意】:定义infinite path: i , p[i], p[p[i]], p[p[p[i]]] ......中所有颜色都相同,那么它就是一条infinite path。即c[i] = c[p[i]] = c[p[p[i]]] = ......。 定义:c = a × b,c[i] = b[a[i]]。求最小的k满足 (p^k(p×...×p)) 中存在至少一个infinite path。

    分析:首先我们应该知道如果存在一个i = p[i]的话或者所有c[i]都相等的话是肯定满足的,那么k就等于1。否则的话它就是一个置换群。首先求出所有环的长度,可以用dfs处理。求出环的长度后,我们只需枚举环的因子,看看所有因子的倍数在环中的颜色是否相同,如果全都相同,那么就可以更新答案。

    #include <bits/stdc++.h>
    #define debug(x) cout << #x << " = " << x << endl; 
    
    using namespace std;
    typedef long long LL;
    const int maxn = 2e5 + 10;
    const int inf = 0x3f3f3f3f;
    const double eps = 1e-6, pi = acos(-1);
    int gcd(int a,int b)    { return b == 0 ? a : gcd(b, a % b); }
    
    int p[maxn], c[maxn], n;
    int vis[maxn];
    vector<int> path;
    void dfs(int now, int val)
    {
        vis[val] = 1;
        if(now == val)  return;
        path.push_back(val);
        dfs(now, p[val]);
    }
    
    int main()
    {
        int t; scanf("%d", &t);
        while(t--){
            scanf("%d", &n);
            int ok = 0, flag = 1;
            for(int i = 1; i <= n; ++i){
                vis[i] = 0;
                scanf("%d", &p[i]);
                if(i == p[i])   ok = 1;
            }
            for(int i = 1; i <= n; ++i){
                scanf("%d", &c[i]);
                if(i > 1 && c[i] != c[i-1]) flag = 0;
            }
            if(ok || flag)  puts("1");
            else{
                int ans = inf;
                for(int i = 1; i <= n; ++i){
                    if(vis[i])  continue;
                    vis[i] = 1;
                    path.clear();   path.push_back(i);      //path记录一个置换群的长度
                    dfs(i, p[i]);   
                    for(int j = 1; j <= path.size(); ++j){  //枚举环的长度的因子
                        if(path.size() % j)     continue;
                        for(int k = 0; k < j; ++k){
                            int ok = 1;
                            for(int z = k; z < path.size(); z += j){
                                if(c[path[k]] != c[path[z]]){
                                    ok = 0;
                                    break;
                                }
                            }
                            if(ok)  ans = min(ans, j);
                        }
                    }
                }
                printf("%d
    ", ans);
            }
        }
    }
    

    E.Count The Blocks

    【题意】:问$ 0 到 10 ^ n - 1$中有多少个连续相等长度为i的块。

    【分析】:首先 i = n时,只有n个0到n个9符合。即答案为10。根据这个我们用组合数学的知识想一想,首先设相等的长度为i,那么它的值能取0 ~ 9中(C_{10}^{1})个数,与他相邻的必须与他不同取(C_{9}^{1})个数。如果那个块在数字的连个边缘,那么它的贡献就是:(C_{10}^{1} * C_{9}^{1} * 10 ^ {n - i - 1} * 2),如果在中间那么它的贡献就是:(C_{10}^{1} * C_{9}^{1} * C_{9}^{1} * (n - i - 2 + 1) * 10 ^ {n - i - 2}),其中(n - i - 2 + 1)表示在n - 2中取长度为 i 的连续长度的个数。

    #include <bits/stdc++.h>
    #define debug(x) cout << #x << " = " << x << endl; 
    
    using namespace std;
    typedef long long LL;
    const int maxn = 2e5 + 10;
    const int inf = 0x3f3f3f3f, mod =  998244353;
    const double eps = 1e-6, pi = acos(-1);
    int gcd(int a,int b)    { return b == 0 ? a : gcd(b, a % b); }
    
    int n;
    LL qpow(LL a, LL b)
    {
        //if(b < 0)   return 0;
        LL ans = 1;
        while(b){
            if(b & 1)   ans = (ans * a) % mod;
            a = a * a % mod;
            b >>= 1;
        }
        return ans;
    }
    
    int main()
    {
        cin >> n;
        //只要那一段属于就可以了,不用管别的段是不是也有长度为i的段
        for(int i = 1; i <= n; ++i){
            if(i == n)  printf("10 ");
            else if(i == n-1)   printf("180 ");
            else{
                LL ans = (18 * qpow(10, n - i) % mod + 81 * qpow(10, n - i - 1) * (n - i - 1) % mod) % mod;
                printf("%lld ",ans);
            }
        }
        puts("");
        //system("pause");
    }
    
  • 相关阅读:
    2013第38周日Java文件上传下载收集思考
    2013年第38周六这一刻,行动
    2013年9月20日突然的焦虑
    2013中秋
    2013第38周三
    2013年第38周二
    2013第38周一电话开会邮件
    for循环中一个不容小觑的问题
    NPOI 创建Excel,数据读取与写入
    linux下mysql数据的导出和导入
  • 原文地址:https://www.cnblogs.com/StungYep/p/12564222.html
Copyright © 2011-2022 走看看