首页 > 其他分享 >Pinely Round 4 (Div. 1 + Div. 2) 补题记录(A~F)

Pinely Round 4 (Div. 1 + Div. 2) 补题记录(A~F)

时间:2024-07-29 10:39:53浏览次数:7  
标签:ok int Pinely scanf long 补题 Div id lld

打成乐子

A

容易证明下标为奇数的地方可以取到,下标为偶数的地方不可以取到。

直接模拟时间复杂度为 \(O(n)\)。

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 1000100;
int a[N];
signed main() {
    int T;
    scanf("%lld", &T);
    while (T--) {
        int n;
        scanf("%lld", &n);
        int mx = 0;
        for (int i = 1; i <= n; ++i) {
            int x;
            scanf("%lld", &x);
            if (i & 1)
                mx = max(mx, x);
        }
        printf("%lld\n", mx);
    }
    return 0;
}

B

根据 \(\text{or}\) 运算为 \(\text{and}\) 运算的逆运算,令 \(a_1=b_1\),\(a_n=b_{n-1}\),\(a_i=b_{i-1}\text{ or }b_i\) 即可满足条件。

时间复杂度为 \(O(n)\)。

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 1000100;
int a[N], b[N];
signed main() {
    int T;
    scanf("%lld", &T);
    while (T--) {
        int n;
        scanf("%lld", &n);
        for (int i = 1; i < n; ++i)
            scanf("%lld", &b[i]);
        a[1] = b[1];
        for (int i = 2; i < n; ++i)
            a[i] = b[i - 1] | b[i];
        a[n] = b[n - 1];
        bool ok = 1;
        for (int i = 1; i < n; ++i)
            if ((a[i] & a[i + 1]) != b[i]) {
                ok = 0;
                break;
            }
        if (ok) {
            for (int i = 1; i <= n; ++i)
                printf("%lld ", a[i]);
            printf("\n");
        } else puts("-1");
    }
    return 0;
}

C

看到 \(40\) 想到 \(2\log\),因此考虑 \(\log\) 算法。

考虑对原序列分治。每一次选取 \(x\) 为 \(\frac{a_1+a_n}{2}\) 然后减去可以 \(2\log\) 构造答案。

特殊的,若 \(\exists\ \!i\in [1,n]\ a_i\not\equiv b_i(\bmod 2)\),则因为绝对值之后相对的奇偶性不会改变,因此此时无解,特判掉即可。

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 1000100;
int a[N], b[N];
signed main() {
    int T;
    scanf("%lld", &T);
    while (T--) {
        int n;
        scanf("%lld", &n);
        for (int i = 1; i <= n; ++i)
            scanf("%lld", &a[i]);
        int ok = a[1] & 1;
        for (int i = 2; i <= n; ++i)
            if (ok != (a[i] & 1)) {
                ok = 2;
                break;
            }
        if (ok == 2)
            puts("-1");
        else {
            vector<int> result;
            for (int j = 0; j < 41; ++j) {
                if (count(a + 1, a + n + 1, 0ll) == n)
                    break;
                if (j == 40) {
                    result.emplace_back(-1);
                    break;
                }
                sort(a + 1, a + n + 1);
                int val = (a[1] + a[n]) / 2;
                result.emplace_back(val);
                for (int k = 1; k <= n; ++k)
                    a[k] = abs(a[k] - val);
            }
            if (result.size() > 40)
                puts("-1");
            else {
                cout << result.size() << '\n';
                for (auto &x : result)
                    printf("%lld ", x);
                puts("");
            }
        }
    }
    return 0;
}

D

Bad Problem

猜测最多可以用 \(4\) 种颜色构造答案。因此人工写一个 \(O(n^2)\) 的 checker 然后扔到程序里面试,得到一组可行的构造为 \(1,2,3,4,1,2,3,4,\ldots\) 。

需要特判 \(n\le 5\) 的情况。

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 400100;
int isprime(int x) {
    if (x < 2) return 0;
    for (int i = 2; i * i <= x; ++i)
    if (x % i == 0) return 0;
    return 1;
}
int f[N], vis[40], g[N];
signed main() {
    // freopen("3.out", "w", stdout);
    int T;
    cin >> T;
    f[1] = 1;
    for (int i=2;i<N;++i)
    for(int j=i+i;j<N;j+=i)
    f[j]=1;
    while (T--) {
        int n;
        scanf("%lld", &n);
        if (n == 1) puts("1\n1");
        else {
            if (n == 2) puts("2\n1 2");
            else if (n == 3) puts("2\n1 2 2");
            else if (n == 4) puts("3\n1 2 2 3");
            else if (n == 5) puts("3\n1 2 2 3 3");
            else {
                puts("4");
                printf("1 2 3 4 1 ");
                const int p[] = {2, 3, 4, 1};
                for (int i = 0; i < n - 5; ++i)
                    printf("%lld ", p[i % 4]);
                puts("");
            }
        }
    }
}

E

容易发现如果要选 Alice 的话那么 Alice 肯定是只用两种颜色最优秀。Alice 能获胜当且仅当图中存在奇环。

那么先对图跑一边黑白染色,如果发现染不了那么存在奇环选 Alice,否则不存在选 Bob。

选 Bob 的时候可以将图中黑点放入集合 \(V_1\),白点放入集合 \(V_2\)。那么如果能用 \(1\) 颜色就用 \(1\) 颜色,能用 \(2\) 颜色就用 \(2\) 颜 色,都不能用就随便拿出来一个点用 \(3\) 颜色,然后就做完了。

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 2e5 + 10;
vector<int> z[N];
int col[N], ok;
void dfs(int u, int now) {
    if (!ok)
        return;
    col[u] = now;
    for (auto &v : z[u])
        if (col[v] == -1) {
            dfs(v, now ^ 1);
            if (!ok)
                return;
        }
        else if (col[v] == col[u]) {
            ok = 0;
            return;
        }
}
signed main() {
    int T;
    cin >> T;
    while (T--) {
        int n, m;
        cin >> n >> m;
        for (int i = 1; i <= n; ++i) {
            z[i].clear();
            col[i] = -1;
        }
        ok = 1;
        while (m--) {
            int u, v;
            cin >> u >> v;
            z[u].emplace_back(v);
            z[v].emplace_back(u);
        }
        dfs(1, 0);
        if (!ok) {
            cout << "Alice" << endl;
            for (int i = 1; i <= n; ++i) {
                cout << "1 2" << endl;
                int x, y;
                cin >> x >> y;
            }
        } else {
            cout << "Bob" << endl;
            vector<int> v1, v2;
            for (int i = 1; i <= n; ++i)
                if (col[i] == 1) v1.emplace_back(i);
                else v2.emplace_back(i);
            for (int i = 1; i <= n; ++i) {
                int x, y;
                cin >> x >> y;
                if (v1.size() && (x == 1 || y == 1)) {
                    cout << v1.back() << " 1" << endl;
                    v1.pop_back();
                } else if (v2.size() && (x == 2 || y == 2)) {
                    cout << v2.back() << " 2" << endl;
                    v2.pop_back();
                } else {
                    if (x > y)
                        swap(x, y);
                    if (x == 1) {
                        if (v1.size())
                            cout << v1.back() << " 1" << endl, v1.pop_back();
                        else
                            cout << v2.back() << " " << y << endl, v2.pop_back();
                    } else {
                        if (v2.size())
                            cout << v2.back() << " 2"  << endl, v2.pop_back();
                        else
                            cout << v1.back() << " " << y << endl, v1.pop_back();
                    }
                }
            }
        }
    }
}

F

定义 \(F_i\) 为第 \(i\) 个斐波那契数,则容易证明 \(F_{50}>10^9\),也就是说 \(2\times 50=100\) 条边就一定可以组成三角形。

现在只需要讨论区间长度 \(\le 100\) 的情况。

将所有在区间范围内的线段从大到小排序,然后第一个三角形一定可以贪心的选权值最大的那一个。第二个三角形贪心的选择和第一个三角形没有重复的边的三角形中,权值最大的那一个即可。时间复杂度为 \(O(qW\log W)\)。其中 \(W\) 为区间长度。

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 2e5 + 10;
int a[N], b[N], id[N];
signed main() {
    int m, q;
    cin >> m >> q;
    for (int i = 1; i <= m; ++i)
        cin >> b[i];
    while (q--) {
        int l, r;
        cin >> l >> r;
        if (r - l + 1 >= 200)
            puts("YES");
        else {
            int n = r - l + 1;
            for (int i = 1; i <= n; ++i)
                a[i] = b[i + l - 1];
            sort(a + 1, a + n + 1, greater<>());
            int cnt = 0;
            for (int i = 1; i <= n - 2; ++i)
                if (a[i + 1] + a[i + 2] > a[i])
                    id[++cnt] = i;
            int gmid = -1;
            for (int i = 1; i <= cnt; ++i)
                if (id[i] - id[1] >= 3) {
                    gmid = id[i];
                    break;
                }
            int mx = -1;
            if (~gmid)
                mx = a[id[1]] + a[id[1] + 1] + a[id[1] + 2] + a[gmid] + a[gmid + 1] + a[gmid + 2];
            if (id[1] + 5 <= n) {
                int p[6] = {a[id[1]], a[id[1] + 1], a[id[1] + 2], a[id[1] + 3], a[id[1] + 4], a[id[1] + 5]};
                sort(p, p + 6);
                int cost = accumulate(p, p + 6, 0ll);
                do {
                    if (p[0] + p[1] > p[2] && p[3] + p[4] > p[5] && p[1] + p[2] > p[0] && p[0] + p[2] > p[1] && p[3] + p[5] > p[4] && p[4] + p[5] > p[3]) {
                        mx = max(mx, cost);
                        break;
                    }
                } while (next_permutation(p, p + 6));
            }
            if (~mx)
                puts("YES");
            else
                puts("NO");
        }
    }
}

标签:ok,int,Pinely,scanf,long,补题,Div,id,lld
From: https://www.cnblogs.com/yhbqwq/p/18329602

相关文章

  • Codeforces Round 961 (Div. 2)
    Preface菜的批爆,B2一直WA道心破碎了直接白兰去了,鉴定为纯纯的飞舞本来想着周末补题的然后又摆了一天,E1和E2都没时间补了,鉴定为纯纯的懒狗A.Diagonals签到,贪心枚举即可#include<cstdio>#include<iostream>#include<utility>#include<vector>#include<cstring>#in......
  • SMU Summer 2024 div2 3rd
    文章目录TheThirdWeek一、前言二、算法1.KMP算法2.线性DP<1>(最长上升子序列II)3.背包DP<1>(「木」迷雾森林)4.其它<1>(Ubiquity)三、总结TheThirdWeek战略上藐视敌人,战术上重视敌人————毛泽东主席一、前言周六打了场cf,只过了俩题而且比较慢,给我的id上......
  • Solution - Atcoder ARC114F Permutation Division
    令\(a\)为题目中的\(P\)。首先考虑后手的重排策略是什么。因为\(a\)是个排列,元素互不相同,那么肯定就是按照每一段的第一个数的大小,越大的放在越前面。那么当\(a_1\lek\)的时候,显然先手会把以\(1\simk\)开头来划分段。因为否则存在一个开头\(>k\)的段,后手把其放......
  • Codeforces Round 962 (Div. 3) 题解 A-F
    A.LegsProblem-A-Codeforces1.1翻译农夫约翰的农场又迎来了美好的一天。农夫约翰来到农场后,数了数n条腿。众所周知,农场里只住着鸡和牛,一只鸡有2条腿,而一头牛有4条腿。假设约翰农场主数清了所有动物的腿,那么他的农场里最少有多少动物?1.2思路求最少有几只动物......
  • Codeforces Round 962 (Div. 3)
    题目链接:CodeforcesRound962(Div.3)总结:ABC秒过,D有点难评了,E优化很妙。A.Legstag:签到voidsolve(){cin>>n;inta=n/4,b=n%4;a+=b/2;cout<<a<<endl;}B.Scaletag:模拟voidsolve(){cin>>n>>k;......
  • AtCoder Beginner Contest 364 补题记录(A~F)
    VP五十八分钟苏童流体。好耶A#defineGLIBCXX_DEBUG#include<iostream>#include<cstring>#include<cstdio>#defineintlonglongconstintN=500100;std::strings[N];signedmain(){intn,cnt=1;scanf("%lld",&n);f......
  • Codeforces Round 962 (Div. 3) A - D详细题解(思路加代码Python,C++(垃圾灰名小白想
             吐槽一下,这次比赛不知道怎么的,可能是div3参加的人比较多吗,代码题解上去后全是inqueue,比赛的过程中我还看了提交的,80多页几千个提交全是inqueue,我的代码等了**半个多小时才运行,然后发现timelimit真的有点搞心态,思路在下一题我还要反过来去优化上一题,不过......
  • Codeforces Round 962 (Div. 3) CDE
    时间:2024-07-27C.Sort原题:C.Sort标签:前缀和题意给定字符串a,b定义\(sorted(a[l..r])\)表示将a的lr区间排序为有序有q次询问,每次给出区间l,r,要求通过操作使\(sorted(a[l..r])==sorted(b[l..r])\)操作为将\(a_i\)变成需要的任意字符,求最少次数思路一开始由于是div3,尝......
  • Codeforces Round 962(Div. 3)
    CodeforcesRound962(Div.3)A.legs题解:简单的贪心,可以对n预处理,将n除以2,此时可将动物视为1,则动物便是1条或两条腿,此时若是奇数才需要鸡,否则全部是牛便是最优解ShowCode#include<bits/stdc++.h>#defineANScout<<ans<<'\n'usingnamespacestd;voidsolve(){......
  • Codeforces Round 962(Div .3)
    CodeforcesRound962(Div.3)A.legs题解:简单的贪心,可以对n预处理,将n除以2,此时可将动物视为1,则动物便是1条或两条腿,此时若是奇数才需要鸡,否则全部是牛便是最优解ShowCode#include<bits/stdc++.h>#defineANScout<<ans<<'\n'usingnamespacestd;voidsolve(){......