• 牛客多校第四场自闭


    自闭场,不想多说,能做的就2个签到和H了,难度2.0就是字典树上后缀自动机,知识储备限制了我的想象

    H-Harder Gcd Problem

    先挂个线性筛把范围内素数都筛一下,然后直接lowerbound找到第一个小于n的素数位置(实际上至少要小于等于n/2,我懒,直接lowerbound到n了),然后从大往小依次处理

    对于每一个素数,让(j=(n/p[i])*p[i])(即找到最后一个j使得jp[i]<=n),然后把j向1枚举,每两个jp[i]组成一对答案,但对于j为奇数的情况,2*p[i]得先暂时保留

    最后再遍历没被匹配的数,这时刚刚2*p[i]中带有2的因子,因此他们也能够相互匹配,这样再把它们两两匹配

    我的处理是先让1*p[i]处于待匹配状态,若j为偶数,则2也能被匹配;若j为奇数,则2只能进入待匹配状态,而不会被匹配

    
    #pragma GCC optimize(2)
    #include<bits/stdc++.h>
    #define ll long long
    #define fastio ios::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
    using namespace std;
    double pi = acos(-1);
    const double eps = 1e-12;
    const int maxn = 4e5 + 10;
    const int inf = 1e9;
    ll mod = 1e9 + 7;
    int read()
    {
        int x = 0, f = 1;
        char c = getchar();
        while (c < '0' || c>'9') { if (c == '-') f = -1; c = getchar(); }
        while (c >= '0' && c <= '9') x = (x << 1) + (x << 3) + c - '0', c = getchar();
        return f * x;
    }
     
    int v[maxn], p[maxn], ecnt, vis[maxn], cnt = 0;
     
     
    void Euler_sieve(int n)
    {
        ecnt = 0;
        for (int i = 2; i <= n; i++) {
            if (v[i] == 0) { v[i] = i; p[++ecnt] = i; }
            for (int j = 1; j <= ecnt; j++)
            {
                if (p[j] > v[i] || p[j] > n / i)break;
                v[i * p[j]] = p[j];
            }
        }
    }
     
    struct an {
        int a, b;
    }ans[maxn];
     
     
    int main()
    {
        fastio;
        int t;
        cin >> t;
        Euler_sieve(3e5 + 5);
        while(t--)
        {
            memset(vis, 0, sizeof(vis));
            int n;
            cin >> n;
            cnt = 0;
            int P = lower_bound(p + 1, p + 1 + ecnt, n) - p - 1;
            int tmp = -1;
            for (int i = P; i >= 1; i--)
            {
                tmp = p[i];
                    for (int j = n / p[i] * p[i]; j > p[i]; j -= p[i])
                    {
                        if (!vis[j])
                        {
                            if (tmp == -1)
                                tmp = j;
                            else
                            {
                                ans[++cnt] = { tmp,j };
                                vis[tmp] = vis[j] = 1;
                                tmp = -1;
                            }
                        }
                    }
            }
            tmp = -1;
            for (int i = 2; i <= n; i += 2)
            {
                if (!vis[i])
                    if (tmp == -1)
                        tmp = i;
                    else
                    {
                        ans[++cnt] = { tmp,i };
                        vis[tmp] = vis[i] = 1;
                        tmp = -1;
                    }
            }
            cout << cnt << endl;
            for (int i = 1; i <= cnt; i++)
                cout << ans[i].a << " " << ans[i].b << endl;
        }
     
        return 0;
     
    }
    


    D-Dividing Strings

    阴间字符串,模拟+思维难度感觉很大

    首先需要知道的是:函数传入大字符串会T,建议直接取地址,具体差多少时间,见图:

    剩下的就是做法了,打的时候想dp想半天没整出来,结果是模拟,我直接爬

    由样例可得到的结论:

    拆成长度为1的n个数,ans肯定<=9,因此枚举长度只有两种(1、拆成长度相同的串;2、拆成长度为d和d-1的串;3否则不能使ans<=9)

    对于长度相同的串,直接找到最大值和最小值比较就行了

    对于长度相差1的串:当且仅当长度为d的串为100000000x,长度为d-1的串为99999999y时相减<=9(反证法:出现其他串时MAX和MIN都可能改变,相减必大于9)

    当d==2时,需要特判1x和y,让MAX=1x,MIN=y(我的代码好像不需要处理这个就能ac,个人写法可能有影响)

    一定要记得把有前导零的串给筛掉(指相同长度的串匹配)



    以下是代码(感谢ac代码帮模拟手残人找出错误)

    #pragma GCC optimize(2)
    #include<bits/stdc++.h>
    #define ll long long
    using namespace std;
    double pi = acos(-1);
    const double eps = 1e-12;
    const int maxn = 1e5 + 10;
    const int inf = 1e9;
    
    string s;
    int ans;
    int pre[maxn];
    
    int dif(string &a, string &b)
    {
        int len = a.length();
        int res = 0;
        for (int i = 0; i < len; i++)
        {
            res = res * 10 + a[i] - b[i];
            if (res >= 9)return 9;
        }
        return res;
    }
    
    void div1(string &s,int d)//一定要取地址,不然无限TLE,下同
    {
        string MAX = "0", MIN = "z";
        string tmp;
        int len = s.length();
        if (d > len / 2)return;
        int i = 0;
        while (i < len)
        {
            tmp = s.substr(i, d);
            if (tmp[0] == '0' && d > 1)return;//筛掉前导零
            MAX = max(tmp, MAX);//stl自带的字典序比较,我直接觉得牛逼
            MIN = min(tmp, MIN);
            i += d;
        }
        ans = min(ans, dif(MAX, MIN));
    }
    
    void div2(string &s, int d)
    {
        int len = s.length();
        int i = 0, MAX = -1, MIN = 10;
        if (d == 1)return;
        if (len - d < d - 1)return;
        while (i < len)//必然只能是长度相差1的1xxxxxxxy和9999999z,出现其他数的话1xxx就可能不是最大,9999..不是最小
        {
            if (s[i] == '1')
            {
                if (i + d > len)return;
                if (pre[i + d - 1] - pre[i + 1])return;
                MAX = max(MAX, s[i + d - 1] - '0');
                i += d;
            }
            else
            {
                if (i + d - 1 > len)return;
                if (pre[i + d - 2] - pre[i] != (d - 2) * 9)
                    return;
                MIN = min(MIN, s[i + d - 2] - '0');
                i += d - 1;
            }
        }
        //cout << MAX << " " << MIN << endl;
        if (MAX == -1 || MIN == 10)return;
        ans = min(ans, 10 - MIN + MAX);
    }
    
    int main()
    {
        ios::sync_with_stdio(false);
        cin.tie(NULL);
        cout.tie(NULL);
        int t;
        cin >> t;
        while(t--)
        {
            int n;
            cin >> n;
            ans = 9;
            cin >> s;
            int len = s.length();
            pre[0] = 0;
            for (int i = 1; i <= len; i++)
                pre[i] = pre[i - 1] + s[i - 1] - '0';
            for (int i = 1; i <= len / 2 + 1; i++)
            {
                if (len % i == 0)
                    div1(s, i);
                div2(s, i);
               // cout << ans << endl;
            }
            printf("%d
    ", ans);
        }
        return 0;
    
    }
    
    
  • 相关阅读:
    .NET 4 上的REST 框架
    WCF Web API 说再见,继承者ASP.NET Web API
    基于盛大的云数据库系统 MongoIC 构建图片系统
    微软以Apache许可协议开源ASP.NET MVC
    Redis 起步
    HttpClient介绍
    Quartz.NET 2.0正式发布
    CodeFirst Migrations随Entity Framework 4.3一同发布
    Redis 在Centos Linux 上的启动脚本
    Quartz.NET的管理工具
  • 原文地址:https://www.cnblogs.com/ruanbaiQAQ/p/13368404.html
Copyright © 2020-2023  润新知