• Codeforces Round #702 (Div. 3)


    题目 A B C D E F G
    场上成绩 AC AC AC WA
    场后成绩 AC AC AC AC AC AC AC
    是否看题解 N N N N Y N Y

    说在前面

    草,E题挂了,没开long long。

    A

    如果((a_i,a_{i + 1}))不满足,那么(a_i leftarrow 2 cdot a_i)

    # include <bits/stdc++.h>
    using namespace std;
    
    const int N = 100;
    
    int t;
    int n;
    int a[N];
    
    int dfs(int l,int r)
    {
        // printf("l = %d,r = %d
    ",min(l,r),max(l,r));
        if(double(max(l,r)) / double(min(l,r)) <= 2.0)
        {
            return 0;
        }
        int mid = min(2 * min(l,r),max(l,r));
        int s = dfs(l,mid) + dfs(r,mid) + 1;
        // printf("l = %d, r = %d, s = %d,mid = %d
    ",l,r,s,mid);
        return s;
    }
    
    int main(void)
    {
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d",&n);
            for(int i = 1; i <= n; i++)
            {
                scanf("%d",&a[i]);
            }
            int total = 0;
            for(int i = 1; i < n; i++)
            {
                total += dfs(a[i],a[i + 1]);
            }
            printf("%d
    ",total);
        }
        return 0;
    }
    

    B

    求出现在的(c_0',c_1',c_2'),分类讨论:

    • 如果都相等,不用改
    • 如果$ > frac{n}{3}$的有一个,就分给另外两个、
    • 如果$ > frac{n}{3}$的有两个,就分给另外一个。
    # include <bits/stdc++.h>
    
    using namespace std;
    
    const int N = 3e4 + 5;
    
    int n,t;
    int a[N];
    
    map<int,map<int,int> > dp;
    
    int c[3];
    
    int delta[3];
    
    int Get(int i,int j)
    {
        if(i == j) return 0;
        if(i == 0 && j == 1) return 1;
        if(i == 0 && j == 2) return 2;
        if(i == 1 && j == 2) return 1;
        if(i == 1 && j == 0) return 2;
        if(i == 2 && j == 0) return 1;
        if(i == 2 && j == 1) return 2;
    }
    
    int main(void)
    {
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d",&n);
            memset(c,0,sizeof(c));
            for(int i = 1; i <= n; i++)
            {
                scanf("%d",&a[i]);
                a[i] = a[i] % 3;
                ++c[a[i]];
            }
            int Begin = n / 3;
            vector <int> C,D;
            for(int i = 0; i <= 2; i++) 
            {
                delta[i] = c[i] - Begin;
                if(delta[i] < 0) C.push_back(i);
                else if(delta[i] > 0) D.push_back(i);
            }
            int ans = 0;
            if(D.size() == 0)
            {
                printf("0
    ");
                continue;
            }
            else
            {
                if(D.size() == 1)
                {
                    for(int i = 0; i < (int)C.size(); i++)
                    {
                        int v = C[i];
                        ans += (-delta[v]) * Get(D[0],v);
                    }
                }
                else
                {
                    //Give C[0]
                    ans += (delta[D[0]]) * Get(D[0],C[0]) + (delta[D[1]]) * Get(D[1],C[0]);
                }
            } 
            printf("%d
    ",ans);
    
        }   
        return 0;
    }
    

    C

    暴力枚举(a),然后(b = sqrt[3]{x - a^3}),判断一下有没有整数解,我这里用的二分,(mathcal{O}(sqrt[3]{n}log{sqrt[3]{n}}))

    # include <bits/stdc++.h>
    
    using namespace std;
    # define int long long
    int t;
    long long x;
    
    long long qfind(long long x,int i)
    {
        long long ans = 0;
        long long l = 1, r = i;
        while(l <= r)
        {
            int mid = (l + r) >> 1;
            if(mid * mid * mid == x) 
            {
                return ans = mid;
            }
            else
            {
                if(mid * mid * mid > x) r = mid - 1; 
                else l = mid + 1;
            }
        }
        return ans;
    }
    
    bool check(void)
    {
        for(long long i = 1; i * i * i <= x; i++)
        {
            long long s = qfind(x - i * i * i,i);
            if(s) 
            {
                return 1;
            }
        }
        return 0;
    }
    
    signed main(void)
    {
        scanf("%lld",&t);
        while(t--)
        {
            scanf("%lld",&x);
            printf("%s
    ",check() ? "YES" : "NO");
        }
        return 0;
    }
    

    D

    根据题意暴力模拟,最大值位置用ST表。单组询问(mathcal{O}(nlog{n} + n))

    # include <bits/stdc++.h>
    using namespace std;
    
    const int N = 105;
    
    int t,n;
    
    vector <int> g[N];
    
    int a[N];
    
    int ST[N][15];
    
    int Log[N];
    
    int id[N];
    
    int root = 0;
    
    void RMQ1(void)
    {
        for(int i = 1; i <= n; i++)
        {
            ST[i][0] = a[i];
        }
        for(int j = 1; (1 << j) <= n; j++)
        {
            for(int i = 1; i + (1 << j) - 1 <= n; i++)
            {
                ST[i][j] = max(ST[i][j - 1],ST[i + (1 << (j - 1))][j - 1]);
            }
        }
    }
    
    int Get(int l,int r)
    {
        int mid = Log[r - l + 1];
        return max(ST[l][mid],ST[r - (1 << mid) + 1][mid]);
    }
    
    int build(int l,int r) // return : root
    {
        if(l == r)
        {
            return l;
        }
        int maxi = id[Get(l,r)];
        int L = 0,R = 0;
        if(l <= maxi - 1) L = build(l,maxi - 1);
        if(maxi + 1 <= r) R = build(maxi + 1,r);
        if(L) 
        {
            g[maxi].push_back(L);
            g[L].push_back(maxi);
        }
        if(R)
        {
            g[maxi].push_back(R);
            g[R].push_back(maxi);
        }
        return maxi;
    }
    
    int dep[N];
    
    void dfs(int x,int fa)
    {
        for(int i = 0; i < (int)g[x].size(); i++)
        {
            int v = g[x][i];
            if(v == fa) continue;
            dep[v] = dep[x] + 1;
            dfs(v,x);
        }
        return;
    }
    
    int main(void)
    {
        scanf("%d",&t);
        Log[2] = 1;
        for(int i = 3; i <= 100; i++) Log[i] = Log[i / 2] + 1;
        while(t--)
        {
            scanf("%d",&n);
            for(int i = 1; i <= n; i++)
            {
                scanf("%d",&a[i]);
                id[a[i]] = i;
            }
            RMQ1();
            for(int i = 1; i <= n; i++)g[i].clear();
            root = build(1,n);
            dep[root] = 0;
            dfs(root,0);
            for(int i = 1; i <= n; i++)
            {
                printf("%d ",dep[i]);
            }
            putchar('
    ');
        }
        return 0;
    }
    

    E

    排个序,如果第(i)个选手是有几率赢的,考虑最优状况,每次都遇到当前最小的值,如果累计的值小于当前最小,那么这个就不行,否则行。
    那么枚举每个数,并且模拟,(mathcal{O}(n^2))
    这样显然过不去。
    然后我们想到:

    在排序后,如果第(i)个行,那么它后面的都行。
    那么我们考虑枚举这个最小的行的值,(mathcal{O}(nlog{n}))

    # include <bits/stdc++.h>
    
    using namespace std;
    
    # define int long long 
    
    const int N = 2e5 + 5;
    
    int t,n;
    
    struct node
    {
        int soc;
        int x;
    }a[N];
    
    bool flag[N];
    
    bool compare(const struct node &x,const struct node &y) {return x.x < y.x;}
    
    bool check(int x)
    {
        int tot = a[x].x;
        for(int i = 1; i <= n; i++)
        {
            if(i == x) continue;
            if(a[i].x <= tot) tot += a[i].x;
            else return false;
        }
        return true;
    }
    
    int qfind(void)
    {
        int l = 1,r = n;
        int ans = n;
        while(l <= r)
        {
            int mid = (l + r) >> 1;
            if(check(mid))
            {
                r = mid - 1;
                ans = mid;
            }
            else l = mid + 1;
        }
        return ans;
    }
    
    signed main(void)
    {
        scanf("%lld",&t);
        while(t--)
        {
            scanf("%lld",&n);
            memset(flag,0,sizeof(flag));
            for(int i = 1; i <= n; i++)
            {
                scanf("%lld",&a[i].x);
                a[i].soc = i;
                // flag[i] = 0;
            }
            sort(a + 1,a + n + 1,compare);
            // int total = 0;
            int tot = 0;
            int C = qfind();
            for(int i = C; i <= n; i++)
            {
                flag[a[i].soc] = 1;
                ++tot;
            }
            printf("%lld
    ",tot);
            for(int i = 1; i <= n; i++)
            {
                if(flag[i])
                {
                    printf("%lld ",i);
                }
            }
            putchar('
    ');
        }
        return 0;
    }
    

    F

    考虑将每个数的出现的次数求出来,但是(a_i le 10^9),就得离散化一下,设其为(c_i)
    (c)排序,枚举(C),对于每个(c_i),如果(c_i < C),就得消到(0),如果(c_i > C),就得消到(C)
    答案即为

    [sum_{i in {x mid c_x < C}} c_x + sum_{i in {x mid c_x > C}} {c_x - C} ]

    整个前缀和。(mathcal{O}(nlog{n}))

    # include <bits/stdc++.h>
    using namespace std;
    
    const int N = 2e5 + 5;
    
    int t,n;
    int a[N],b[N],c[N];
    long long q[N];
    
    int qfind(int C)
    {
        int l = 1, r = n;
        int ans = n;
        while(l <= r)
        {
            int mid = (l + r) >> 1;
            if(c[mid] < C)
            {
                ans = mid;
                l = mid + 1;
            }
            else r = mid - 1;
        }
        return ans;
    }
    
    int main(void)
    {
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d",&n);
            for(int i = 1; i <= n; i++) c[i] = 0;
            for(int i = 1; i <= n; i++)
            {
                scanf("%d",&a[i]);
                b[i] = a[i];
            }
            sort(b + 1, b + n + 1);
            int Len = unique(b + 1, b + n + 1) - b - 1;
            for(int i = 1; i <= n; i++)
            {
                a[i] = lower_bound(b + 1, b + Len + 1, a[i]) - b;
                ++c[a[i]];
            }
            // sort(a + 1, a + n + 1);
            sort(c + 1, c + n + 1);
            bool flag = 1;
            for(int i = 1; i < n; i++)
            {
                if(c[i] != c[i + 1])
                {
                    flag = 0;
                    break;
                }
            }
            if(flag)
            {
                printf("0
    ");
                continue;
            }
            q[0] = 0;
            for(int i = 1; i <= n; i++)
            {
                q[i] = q[i - 1] + c[i];
            }
            int ans = n;
            for(int C = 0; C <= n; C++)
            {
                int w = qfind(C);
                int ANS = 0;
                ANS = q[w];
                ANS = ANS + q[n] - q[w];
                ANS = ANS - (n - w) * C;
                ans = min(ans,ANS);
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
    

    G

    (q_i = sum_{j = 1} ^ i a_j,Max_i = max_{j = 1} ^ i {q_j})

    显而易见: 如果(Max_n < x)(q_x le 0),输出(-1)

    显而易见(r = left lceil dfrac{x - Max_n}{q_n} ight ceil),其中(r)为对于询问(x)整圈数

    证明: 最小化(r cdot q_n + Max_n ge x (r in mathbb{N_+})),显然取(r = left lceil dfrac{x - Max_n}{q_n} ight ceil)

    如果还有残圈就在(Max)里二分就行,(Max)显然具有单调性,即(Max_i ge Max_{i - 1}(1 < i le n))

    # include <bits/stdc++.h>
    using namespace std;
    
    const int N = 2e5 + 5;
    
    int t,n,m;
    long long a[N];
    long long x[N];
    long long q[N],Max[N];
    int main(void)
    {
        // freopen("G.out","w",stdout);
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d%d",&n,&m);
            for(int i = 1; i <= n; i++)
            {
                scanf("%lld",&a[i]);
            }
            for(int i = 0; i <= n; i++) Max[i] = -1e12;
            for(int i = 1; i <= n; i++) 
            {
                q[i] = q[i - 1] + a[i];
                Max[i] = max(Max[i - 1],q[i]);
            }
            for(int i = 1; i <= m; i++)
            {
                scanf("%lld",&x[i]);
                if(Max[n] < x[i] && q[n] <= 0)
                {
                    printf("-1 ");
                    continue;
                }
                long long r = 0;
                if(Max[n] < x[i])
                {
                    r = ceil(double(x[i] - Max[n]) / double(q[n]));
                    x[i] -= r * q[n]; 
                }
                int j = lower_bound(Max + 1, Max + n + 1, x[i]) - Max;
                printf("%lld ",r * n + j - 1);
               
            }
            putchar('
    ');
        }
        return 0;
    }
    
  • 相关阅读:
    lms框架服务注册中心
    lms框架应用服务接口和服务条目详解
    lms框架模块详解
    lms微服务框架主机介绍
    lms框架分布式事务使用简介
    MySQL锁总结
    VSCode 输出 java SSL 请求过程
    PowerShell自动化发布SpringBoot项目到Tomcat
    AWS EC2 使用---安装Docker和Nginx
    使用PowerShell连接到Linux
  • 原文地址:https://www.cnblogs.com/luyiming123blog/p/14408285.html
Copyright © 2020-2023  润新知