Educational Codeforces Round 168 (Rated for Div. 2)

A. Strong Password

只需要在相邻字母相同的位置插入一个不同的即可,如果没有这种位置,就在字符串末尾插入一个与当前末尾不同的字符即可

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <bits/stdc++.h>
using namespace std;

void solve() {
    string s, ans;
    cin >> s;
    int pos = -1;
    for (int i = 1; i < s.size(); i++) {
        if (s[i] == s[i - 1]) {
            pos = i;
            break;
        }
    }
    if (pos == -1) {
        ans = s + (s[s.size() - 1] == 'a' ? 'b' : 'a');
    } else {
        if (s[pos] == 'a') ans = s.substr(0, pos) + "b" + s.substr(pos, s.size() - pos);
        else ans = s.substr(0, pos) + "a" + s.substr(pos, s.size() - pos);
    }
    cout << ans << endl;
}

int main() {
    int t;
    cin >> t;
    while (t--) solve();
    return 0;
}

B. Make Three Regions

初始时只会有一个联通块,且只有两行,那么要把它分为 3 块,只能找

这种形状的区域

只需要枚举找到即可

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <bits/stdc++.h>
using namespace std;
#define ls now<<1
#define rs now<<1|1
#define endl "\n"
#define lowbit(x) ((x)&(-x))
typedef long long ll;
const int N=2e5+7, mod=1e9+7;

int n;
string s;
int a[3][N];

void solve(){
    cin>>n;
    for(int i=1;i<=2;i++){
        cin>>s;
        for(int j=0;j<n;j++){
            a[i][j+1]=(s[j]=='.'?1:-1);
        }
    }
    int ans=0;
    for(int i=2;i<n;i++){
        if(a[1][i-1]==-1&&a[1][i]==1&&a[1][i+1]==-1&&a[2][i-1]==1&&a[2][i]==1&&a[2][i+1]==1)ans++;
        else if(a[2][i-1]==-1&&a[2][i]==1&&a[2][i+1]==-1&&a[1][i-1]==1&&a[1][i]==1&&a[1][i+1]==1)ans++;
    }
    cout<<ans<<endl;
}

int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);
    int t=1;
    cin>>t;
    while(t--)solve();
    return 0;
}

C. Even Positions

先填充右括号,把已有的左括号全对应上,再全部填充左括号即可

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <bits/stdc++.h>
using namespace std;

void solve(){
    int n;
    string s;
    cin>>n>>s;
    int cnt=0,ans=0;
    for(int i=1;i<n;i+=2){
        if(s[i]=='(')cnt++;
    }
    for(int i=0;i<n;i+=2){
        if(i&&s[i-1]=='('&&cnt)s[i]=')';
        else s[i]='(';
    }
    // cout<<s<<endl;
    deque<int>q;
    for(int i=0;i<n;i++){
        if(s[i]=='(')q.push_back(i);
        else ans+=(i-q.front()),q.pop_front();
    }
    cout<<ans<<endl;
}

int main(){
    int t;
    cin>>t;
    while(t--)solve();
    return 0;
}

D. Maximize the Root

要使根节点最大,就要使子节点都趋近一个值,从而使根节点加 $1$ 的操作最多

用 $dfs$ 向下查找每个子树中的最小值 $mn$,当前根如果比 $mn$ 小,那就需要先对这个根进行几次操作,平衡 $mn$ 之后再向上,如果当前根大于 $mn$,将其视作 $mn$ 即可

最后答案即为 $a[1] + mn$

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include <bits/stdc++.h>
using namespace std;
#define int long long

vector<int>g[300001];
vector<int>a(300001);

void dfs(int x){
    int mn=1e16;
    for(auto u:g[x]){
        dfs(u);
        mn=min(mn,a[u]);
    }
    if(mn==1e16)return;
    if(x==1){a[1]+=mn;return;}
    if(a[x]<mn)a[x]=(a[x]+mn)/2;
    else a[x]=mn;
}

void solve(){
    int n,x;
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>a[i];
        g[i].clear();
    }
    for(int i=2;i<=n;i++){
        cin>>x;
        g[x].push_back(i);
    }
    dfs(1);
    cout<<a[1]<<endl;
}

signed main(){
    int t;
    cin>>t;
    while(t--)solve();
    return 0;
}

E. Level Up

200+ 测试点,哈人

没有修改的操作,所以可以想到预处理

对于每一只怪兽,在 $k>x$ 时,他一定不逃跑,这个 $x$ 即为对应的阀值

在求阀值的过程中,可以采用二分答案来查询先前有多少个下标满足条件

即用权值线段树,看当前 $k$ 出现了多少次

每次计算得到一个阀值 $x$ 后,将 $x->n$ 整体加一

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
#include <bits/stdc++.h>
using namespace std;
#define ls now<<1
#define rs now<<1|1
#define endl "\n"
#define lowbit(x) ((x)&(-x))
typedef long long ll;
const int N=2e5+7, mod=1e9+7;

int tr[N<<2];

int a[N],n,k,id,q,b[N];

void build(int now,int l,int r){
    if(l==r){
        tr[now]=0;
        return;
    }
    int mid=(l+r)>>1;
    build(ls,l,mid);
    build(rs,mid+1,r);
}

void pushdown(int now){
    if(tr[now]){
        tr[ls]+=tr[now];
        tr[rs]+=tr[now];
        tr[now]=0;
    }
}

void change(int now,int l,int r,int s,int t,int val){
    if(s<=l&&r<=t){
        tr[now]+=val;
        return;
    }
    pushdown(now);
    int mid=(l+r)>>1;
    if(s<=mid)change(ls,l,mid,s,t,val);
    if(t>mid)change(rs,mid+1,r,s,t,val);
}

int query(int now,int l,int r,int id){
    if(l==r)return tr[now];
    pushdown(now);
    int mid=(l+r)>>1;
    if(id<=mid)return query(ls,l,mid,id);
    else return query(rs,mid+1,r,id);
}

void solve(){
    cin >> n >> q;
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
    }
    build(1, 1, n);
    change(1,1,n,1,n,1);
    for(int i=2;i<=n;i++){
        int l=1,r=n,ans=0;
        while(l<=r){
            int mid=(l+r)>>1;
            if(query(1,1,n,mid)/mid+1>a[i])l=mid+1;
            else ans=mid,r=mid-1;
        }
        b[i]=ans;
        change(1,1,n,ans,n,1);
    }
    while (q--) {
        cin >> id >> k;
        if(b[id]<=k)cout<<"Yes\n";
        else cout<<"No\n";
    }
}

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    int t = 1;
    // cin >> t;
    while (t--) solve();
    return 0;
}
Licensed under CC BY-NC-SA 4.0
最后更新于 Sep 11, 2025 16:27 +0800
发表了95篇文章 · 总计15万2千字
永远相信美好的事情即将发生。
使用 Hugo 构建
主题 StackJimmy 设计