首页 > 其他分享 >Codeforces Round 973 (Div. 2)

Codeforces Round 973 (Div. 2)

时间:2024-09-25 23:23:41浏览次数:9  
标签:973 cur int sum Codeforces else ok return Div

C. Password Cracking (C)

若字符串只向一个方向延伸,则一定能通过 \(2n\) 次询问获得结果;可以先向后猜测,当该侧继续添加字符1与0都不符合要求时、说明已经到达字符串末端,继续询问前缀即可。

void solve() {
    int n;
    cin >> n;
    string s = "";
    bool flag = 0;
    while(s.size() < n) {
        if(flag) {
            cout << "? 0" << s << endl; // 似乎endl自带清空缓存区的功能
            int ok;
            cin >> ok;
            if(ok) s = "0" + s;
            else s = "1" + s;
        } else {
            cout << "? " << s << '0' << endl;
            int ok;
            cin >> ok;
            if(ok) s += "0";
            else {
                cout << "? " << s << '1' << endl;
                cin >> ok;
                if(ok) s += "1";
                else flag = 1;
            }
        }
    }
    cout << "! " << s << endl;
}

D. Minimize the Difference (D)

似乎挺典的一道题,虽然vp的时候先写E去了没过

由于每次操作只能对前项减1、后项加1,得到的最终序列一定单调不降。用单调栈维护最终序列中元素的大小与数量,后项出现较小数时依次出栈,即可保证复杂度为 \(O(n)\).(有一说一题解的单调栈写得比我好看多了,呜)

void solve() {
    int n;
    scanf("%d", &n);
    for(int i = 1; i <= n; i++) {
        scanf("%lld", &a[i]);
    }
    int it = 0;
    for(int i = 1; i <= n; i++) {
        ll sum = a[i];
        int cur = 1;
        while(it && s[it] >= sum / cur) {
            sum += s[it] * cnt[it];
            cur += cnt[it];
            it--;
        }
        if(sum % cur) {
            s[it + 1] = sum / cur, s[it + 2] = sum / cur + 1;
            cnt[it + 1] = cur - (sum % cur), cnt[it + 2] = sum % cur;
            it += 2;
        } else {
            s[it + 1] = sum / cur, cnt[it + 1] = cur;
            it++;
        }
    }
    printf("%lld\n", s[it] - s[1]);
}

另有:lzz用二分过的,明天去学学他的写法)

E. Prefix GCD (E)

使用上一场D题的结论可以很快做出这题,每次贪心地将能够最小化gcd的值换到当前位置上,若gcd已经达到最小值,之后元素顺序对答案没有影响。

void solve() {
    int n;
    scanf("%d", &n);
    int g = 0;
    for(int i = 1; i <= n; i++) {
        scanf("%d", &a[i]);
        g = __gcd(g, a[i]);
    }
    sort(a + 1, a + n + 1);
    int cur = 0;
    for(int i = 1; i <= n; i++) {
        int mg = INF, mi;
        for(int j = i; j <= n; j++) {
            int d = __gcd(cur, a[j]);
            if(d < mg) mg = d, mi = j;
        }
        swap(a[i], a[mi]);
        cur = mg;
        if(mg == g) break;
    }
    cur = 0;
    ll ans = 0;
    for(int i = 1; i <= n; i++) {
        cur = __gcd(cur, a[i]);
        ans += cur;
    }
    printf("%lld\n", ans);
}

(虽然上场D题现在还是TLE状态,但至少结论记住了,也算补完了吧

F1. Game in Tree (Easy Version) (F1)

游戏过程可抽象为:Alice和Bob沿 \(1\) 至 \(u\) 的最短路径相向而行,可以选择在任一时刻进入当前节点下与路径不重合的子树,而子树的最大深度是确定的,可以预处理得到。对Alice而言,若当前最大深度与其经过的长度之和已经大于Bob可以选择的路径最大值,进入子树即为必胜态;对Bob同理。若两人一直选择留在路径上,判断相遇时的步数差即可。

// 这题我的代码好难看。。。
vector <int> v[N];
int dep[N], fa[N];
void pre(int f, int i) {
    fa[i] = f, dep[i] = dep[f] + 1;
    for(int t : v[i]) {
        if(t == f) continue;
        pre(i, t);
    }
}
int mx[N], sub[N];
bool on[N];
void dfs(int i) {
    mx[i] = sub[i] = dep[i];
    for(int t : v[i]) {
        if(t == fa[i]) continue;
        dfs(t);
        if(!on[t]) sub[i] = max(sub[i], mx[t]);
        mx[i] = max(mx[i], mx[t]);
    }
}
int len, p[N], sa[N][20], sb[N][20];
int qa(int l, int r) {
    if(l > r) return 0;
    int k = __lg(r - l + 1);
    return max(sa[l][k], sa[r - (1 << k) + 1][k]);
}
int qb(int l, int r) {
    if(l > r) return 0;
    int k = __lg(r - l + 1);
    return max(sb[l][k], sb[r - (1 << k) + 1][k]);
}
void solve() {
    int n;
    scanf("%d", &n);
    for(int i = 1; i <= n; i++) {
        v[i].clear();
    }
    for(int i = 1; i < n; i++) {
        int x, y;
        scanf("%d%d", &x, &y);
        v[x].push_back(y);
        v[y].push_back(x);
    }
    pre(0, 1);
    int a, b;
    scanf("%d%d", &a, &b);
    len = 0;
    fill(on + 1, on + n + 1, 0);
    for(int i = a; i; i = fa[i]) {
        p[++len] = i, on[i] = 1;
    }
    dfs(1);
    for(int i = 1; i <= len; i++) {
        sa[i][0] = sub[p[i]];
        int d = len - i;
        if(d < i) sa[i][0] = max(sa[i][0], d + (len - d * 2 + 1) / 2);
        sb[i][0] = i + sub[p[i]] - dep[p[i]];
    }
    for(int k = 1; k <= __lg(len); k++) {
        for(int i = 1; i + (1 << k) - 1 <= len; i++) {
            sa[i][k] = max(sa[i][k - 1], sa[i + (1 << k - 1)][k - 1]);
            sb[i][k] = max(sb[i][k - 1], sb[i + (1 << k - 1)][k - 1]);
        }
    }
    for(int i = 1; i <= len / 2; i++) {
        int j = len - i + 1;
        if(sa[j][0] > qb(i, j - 1)) {
            printf("Alice\n");
            return;
        }
        if(i == j - 1) break;
        if(sb[i][0] >= qa(i + 1, j - 1)) {
            printf("Bob\n");
            return;
        }
        if(i == j - 2) break;
    }
    if(len & 1) printf("Alice\n");
    else printf("Bob\n");
}

(F2还没补完)

标签:973,cur,int,sum,Codeforces,else,ok,return,Div
From: https://www.cnblogs.com/meowqwq/p/18430919

相关文章

  • Codeforces Round 971 (Div. 4)A~G1
    CodeforcesRound971(Div.4)A~G1A.Minimize!签到不多说。//AConemoretimes//nndbk#include<bits/stdc++.h>usingnamespacestd;typedeflonglongll;constintmod=1e9+7;constintN=2e5+10;intmain(){ ios::sync_with_stdio(false......
  • Codeforces Round 974 (Div. 3)题解记录
    A.RobinHelps签到模拟,遍历一遍即可,注意没钱时不给钱。\(O(n)\)#include<iostream>#include<set>#include<map>#include<vector>#include<algorithm>#include<bitset>#include<math.h>#include<string>#include<string.h>#......
  • Codeforces Round 959 (Div. 1 + Div. 2) C. Hungry Games题解
    CodeforcesRound959(Div.1+Div.2)C.HungryGames题解题目链接大致题意:给定一个长度为n的数组,并且给出一对l,r表示一个区间,如果∑i......
  • Codeforces Round 974 (Div.3) 题解
    CodeforcesRound974(Div.3)题解A.RobinHelps模拟按照题意模拟即可。voidShowball(){intn,k;cin>>n>>k;intcur=0,ans=0;for(inti=0;i<n;i++){intx;cin>>x;if(x>=k)cur+=x;elseif(!x){if(cur>=1)cu......
  • codeforces round 974(div.3) D(学会灵活拆分数据)
    解题历程:首先想到的是用数组记录,遍历每一个任务的区间,对区间内的数值加1,比如对于发生在4和8天之内的任务,a[4]++,a[5]++……a[8]++。然后用双指针,记录持续天数的开始下标和结束下标,以l和l+d为边界的窗口遍历每一天,若是最高位寻找任务最多的一天,和区间最大值最小的一天。后来发现......
  • p标签不能嵌套div,h1~h6,p,如果嵌套浏览器会如何解析
    有时候做项目会不小心用p嵌套div,发现控制不了样式,我们放到最后去讲p嵌套div的问题首先,我们先用p标签来嵌套h1~h6,这里我选择h1(h1~h6测试结果都一样),上代码及效果图让我们看下浏览器如何解析我们发现,浏览器把h1标签给单独摘出来了,并且多了个p标签,导致这样的原因:看代码图:首......
  • Codeforces Round 973 (Div. 2)
    A.Zhan'sBlender有\(n\)个水果,每秒可以消耗\(\min\{x,y\}\)个,问需要多少时间。整数除法的上取整操作即可。点击查看代码#include<bits/stdc++.h>usingnamespacestd;#definelllonglong#defineullunsignedlonglongintread(){intx=0;boolf=......
  • Codeforces Round 972(Div.2)题解
    CodeforcesRound972(Div.2)题解A.SimplePalindrome贪心贪心,尽可能元素数量平均,并且相同字母放在一起。#include<bits/stdc++.h>usingnamespacestd;#definefffirst#definesssecond#definepbpush_back#defineall(u)u.begin(),u.end()#defineendl'\n'#de......
  • Codeforces Round 973 (Div.2) A-E题解
    CodeforcesRound973(Div.2)A-E题解比赛传送门A.Zhan'sBlender数学显然答案为\(\lceil\frac{n}{min(x,y)}\rceil\)。#include<bits/stdc++.h>usingnamespacestd;#definefffirst#definesssecond#definepbpush_back#defineall(u)u.begin(),u.en......
  • codeforces 1041 C. Coffee Break
    题意第一行输入三个整数\(n,m,d(1\leqn\leq2*10^5,n\leqm\leq10^9,1\leqd\leqn)\),第二行输入\(n\)个整数,保证每个数均不大于\(m\)。在每一天你都可以任意选择一个未选过的数\(a_i\),随后可以继续选任意一个大于\(a_i+d\)的数\(a_j\);接下来可以再选任意......