【CodeForces训练记录】Educational Codeforces Round 177 (Rated for Div. 2)

训练情况

赛后反思

A题题目读太久了,被D题的动态规划创死了,没有头绪想不到做法

A题

阅读理解,有效的部分为三分之二,答案最后还要乘个三,分母约掉,直接等效于直接乘二,我们直接乘二输出即可

点击查看代码
#include <bits/stdc++.h>
// #define int long long
#define endl '\n'

using namespace std;

void solve(){
    int x; cin>>x;
    cout<<x*2<<endl;
}

signed main(){
	ios::sync_with_stdio(false);
	cin.tie(0),cout.tie(0);
    int T; cin>>T; while(T--)
    solve();
    return 0;
}

B题

题目所述选择的左区间要尽可能多,所选区间和最大,我们直接取 \(r = n\),现在问题就能转换成 \([l,n]\) 区间和至少为 \(x\),我们先对长度为 \(n\) 的区间求和,求 \(x\) 中有几个这样的区间和,每个区间长度为 \(n\),先扣除掉整个整个的区间,接下来就是区间从后往前找,直到大于等于 \(x\) 为止

点击查看代码
#include <bits/stdc++.h>
#define int long long
#define endl '\n'

using namespace std;

void solve(){
    int n,k,x; cin>>n>>k>>x;
    vector<int> a(n + 1);
    int sum = 0;
    for(int i = 1;i<=n;i++) cin>>a[i],sum+=a[i]; 
    int ans = n*k;
    ans -= x/sum*n;
    x -= x/sum*sum;
    for(int i = n;i;i--) if(x>0) x-=a[i],ans--;
    cout<<max(0ll,ans+1)<<endl;
}

signed main(){
	ios::sync_with_stdio(false);
	cin.tie(0),cout.tie(0);
    int T; cin>>T; while(T--)
    solve();
    return 0;
}

C题

这题我们手玩发现,每次修改位置 \(x\)\(0\),想要恢复排列,位置 \(x\) 上的数只能是 \(x\),那么其他位置上要是有 \(x\) 这个数就也要改,我们显然发现是一个 \(p_i \neq i\) 的联通块,只要联通块内任何一个数被替换,联通块所有数都要改掉,对答案的贡献为联通块大小,所以我们考虑并查集维护联通块的传递性,我们按照 \(d_i\) 的顺序遍历,遇到新的联通块就计算答案贡献即可

点击查看代码
#include <bits/stdc++.h>
// #define int long long
#define endl '\n'

using namespace std;

const int N = 1e5 + 3;

int fa[N];

int Find(int x){
    if(fa[x] < 0) return x;
    return fa[x] = Find(fa[x]);
}

void Union(int x,int y){
    x = Find(x); y = Find(y);
    if(x == y) return;
    fa[y] += fa[x];
    fa[x] = y;
}

void solve(){
    int n; cin>>n;
    for(int i = 1;i<=n;i++) fa[i] = -1;
    vector<int> p(n + 1),d(n + 1),c(n + 1),cc(n + 1);
    for(int i = 1;i<=n;i++) cin>>p[i];
    for(int i = 1;i<=n;i++) cin>>d[i];
    for(int i = 1;i<=n;i++){
        int now = i;
        while(p[now] != now && !c[now]){
            c[now] = 1;
            Union(now,p[now]);
            now = p[now];
        }
    }
    // for(int i = 1;i<=n;i++){
    //     cout<<Find(i);
    // } cout<<endl;
    int ans = 0;
    for(int i = 1;i<=n;i++){
        if(!cc[Find(d[i])]){
            cc[Find(d[i])] = 1;
            ans += -fa[Find(d[i])];
        }
        cout<<ans<<" ";
    }
    cout<<endl;
}

signed main(){
	ios::sync_with_stdio(false);
	cin.tie(0),cout.tie(0);
    int T; cin>>T; while(T--)
    solve();
    return 0;
}
posted @ 2025-04-04 00:42  MNNUACM_2024ZY  阅读(420)  评论(2)    收藏  举报