Codeforces Round #779 (Div. 2)

CF系列题解(又是心态炸裂的一场)


题目

A. Marin and Photoshoot

原题链接

A. Marin and Photoshoot

题意

给定一个长度为 n n n 01 01 01 串,可以添加若干个 1 1 1,使得任意区间内 0 0 0 的个数不超过 1 1 1 的个数。

读题没读明白,还是靠队友才懂,吐了啊。。。

输入格式
第一行包含一个整数 t ( 1 ≤ t ≤ 1 0 3 ) t (1≤t≤10^3) t(1t103) ,表示有t组测试数据。
每个测试数据第一行包含一个个整数 n ( 1 ≤ n ≤ 100 ) n (1≤n≤100) n(1n100)
每个测试数据第二行包含一个字符串 s s s

输出格式
输出需要添加 1 1 1 的个数

输入样例:

9
3
000
3
001
3
010
3
011
3
100
3
101
3
110
3
111
19
1010110000100000101

输出样例:

4
2
1
0
2
0
0
0
17

题解

思路

保证每两个 0 0 0 中间至少有两个 1 1 1 即可。

代码

#include <bits/stdc++.h>

// #define int long long

using namespace std;

typedef long long LL;

void solve()
{
    int n;
    cin >> n;

    string s;
    cin >> s;

    int ans = 0;
    for (int i = 0; i < n; i ++ ) {
        if (s[i] == '0') {
            int j = i + 1;
            while (j < n && s[j] == '1') j ++ ;
            if (j < n && j - i - 1 < 2) {
                ans += 2 - (j - i - 1);
            }
            i = j - 1;
        }
    }
    cout << ans << "\n";
}

signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int T;
    cin >> T;

    while (T -- ) {
        solve();
    }

    return 0;
}

B. Marin and Anti-coprime Permutation

原题链接

B. Marin and Anti-coprime Permutation

题意

p p p 排列的个数,使得:
g c d ( 1 ⋅ p 1 , 2 ⋅ p 2 , … , n ⋅ p n ) > 1 gcd(1⋅p_1,2⋅p_2,…,n⋅p_n)>1 gcd(1p1,2p2,,npn)>1

输入格式
第一行包含一个整数 t ( 1 ≤ t ≤ 1 0 3 ) t (1≤t≤10^3) t(1t103) ,表示有t组测试数据。
每个测试数据包含一个整数 n ( 1 ≤ n ≤ 1 0 3 ) n(1≤n≤10^3) n(1n103)

输出格式
输出排列的个数,由于可能会很大,因此对 998244353 998244353 998244353 取模。

输入样例:
7
1
2
3
4
5
6
1000

输出样例:
0
1
0
4
0
36
665702330

题解

思路

我们假设 g c d = k gcd=k gcd=k [ 1 , n ] [1,n] [1,n] 中具有因子 k k k 的数有 [ n / k ] [n/k] [n/k] 个,因此原式一共就只有 2 × [ n / k ] 2×[n/k] 2×[n/k] 个因子 k k k ,由于 k > 1 k>1 k1 ,因此 k k k 只能为 2 2 2

因此我们只要把奇数的 p p p 放到 2 , 4 , . . . 2,4,... 2,4,... 之类的偶数上,偶数 p p p 放到 1 , 3 , . . . 1,3,... 1,3,... 之类的奇数上即可,方案数为 ( ( n / 2 ) ! ) 2 ((n/2)!)^2 ((n/2)!)2

代码

#include <bits/stdc++.h>

#define int long long

using namespace std;

typedef long long i64;

const int p = 998244353;

void solve()
{
    int n;
    cin >> n;

    if (n % 2) {
        cout << "0\n";
        return;
    }

    int ans = 1;
    for (int i = n / 2; i; i -- ) {
        ans = ans * i % p * i % p;
    }

    cout << ans << "\n";
}

signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int T;
    cin >> T;

    while (T -- ) {
        solve();
    }

    return 0;
}

C. Shinju and the Lost Permutation

原题链接

C. Shinju and the Lost Permutation

题意

给定一个全排列 p = [ p 1 , p 2 , … , p n ] p=[p_1,p_2,…,p_n] p=[p1,p2,,pn] ,定义一个操作(不会翻译) o p i op_i opi ,使得 p p p 变为 p = [ p n − i + 1 , … , p n , p 1 , p 2 , … , p n − i ] p=[p_{n−i+1},…,p_n,p_1,p_2,…,p_{n−i}] p=[pni+1,,pn,p1,p2,,pni]
举个栗子:
[ 5 , 1 , 2 , 4 , 6 , 3 ] [5,1,2,4,6,3] [5,1,2,4,6,3] 经过 o p 0 op_0 op0 变为 [ 5 , 1 , 2 , 4 , 6 , 3 ] [5,1,2,4,6,3] [5,1,2,4,6,3]
[ 5 , 1 , 2 , 4 , 6 , 3 ] [5,1,2,4,6,3] [5,1,2,4,6,3] 经过 o p 1 op_1 op1 变为 [ 3 , 5 , 1 , 2 , 4 , 6 ] [3,5,1,2,4,6] [3,5,1,2,4,6]
[ 5 , 1 , 2 , 4 , 6 , 3 ] [5,1,2,4,6,3] [5,1,2,4,6,3] 经过 o p 2 op_2 op2 变为 [ 6 , 3 , 5 , 1 , 2 , 4 ] [6,3,5,1,2,4] [6,3,5,1,2,4]

定义全排列 p p p m a x max max 数组为 b i = m a x ( p 1 , p 2 , … , p i ) b_i=max(p_1,p_2,…,p_i) bi=max(p1,p2,,pi) p o w e r power power m a x max max 数组中不同数的个数。
举个栗子:
p = [ 5 , 1 , 2 , 4 , 6 , 3 ] p=[5,1,2,4,6,3] p=[5,1,2,4,6,3] b = [ 5 , 5 , 5 , 5 , 6 , 6 ] b=[5,5,5,5,6,6] b=[5,5,5,5,6,6] b b b 中不同数的个数为 2 2 2 ,因此 p o w e r = 2 power=2 power=2
p = [ 3 , 5 , 1 , 2 , 4 , 6 ] p=[3,5,1,2,4,6] p=[3,5,1,2,4,6] b = [ 3 , 5 , 5 , 5 , 5 , 6 ] b=[3,5,5,5,5,6] b=[3,5,5,5,5,6] b b b 中不同数的个数为 3 3 3 ,因此 p o w e r = 3 power=3 power=3
p = [ 6 , 3 , 5 , 1 , 2 , 4 ] p=[6,3,5,1,2,4] p=[6,3,5,1,2,4] b = [ 6 , 6 , 6 , 6 , 6 , 6 ] b=[6,6,6,6,6,6] b=[6,6,6,6,6,6] b b b 中不同数的个数为 1 1 1 ,因此 p o w e r = 1 power=1 power=1

我们定义 c 0 , c 1 , … , c n − 1 c_0,c_1,…,c_{n-1} c0,c1,,cn1 数组为全排列 p p p 经过操作 o p i op_i opi 后的得到的排列的 p o w e r power power 值。

给定我们 c 0 , c 1 , … , c n − 1 c_0,c_1,…,c_{n-1} c0,c1,,cn1 数组,问我们能否构造出 p p p

注:题面太阴间了,因此题主所写题意可能和原题中下标不同,理解题意即可,实在不行看一看样例解释。

输入格式
第一行包含一个整数 t ( 1 ≤ t ≤ 5 × 1 0 3 ) t (1≤t≤5×10^3) t(1t5×103) ,表示有t组测试数据。
每个测试数据第一行包含一个整数 n ( 1 ≤ n ≤ 1 0 5 ) n(1≤n≤10^5) n(1n105) ,表示序列长度。
每个测试数据第二行包含 n n n 个整数 c 0 , c 1 , … , c n − 1 ( 1 ≤ c i ≤ n ) c_0,c_1,…,c_{n-1}(1≤c_i≤n) c0,c1,,cn1(1cin) 表示给定的序列。
n n n 的总和不会超过 1 0 5 10^5 105

输出格式
若有满足 c c c p p p 数组,输出 YES ,否则输出 NO

输入样例:
6
1
1
2
1 2
2
2 2
6
1 2 4 6 3 5
6
2 3 1 2 3 4
3
3 2 1

输出样例:
YES
YES
NO
NO
YES
NO

Note:
In the first test case, the permutation [ 1 ] [1] [1] satisfies the array c c c.

In the second test case, the permutation [ 2 , 1 ] [2,1] [2,1] satisfies the array c c c.

In the fifth test case, the permutation [ 5 , 1 , 2 , 4 , 6 , 3 ] [5,1,2,4,6,3] [5,1,2,4,6,3] satisfies the array c c c. Let’s see why this is true.

  • The zeroth cyclic shift of p p p is [ 5 , 1 , 2 , 4 , 6 , 3 ] [5,1,2,4,6,3] [5,1,2,4,6,3]. Its power is 2 2 2 since b = [ 5 , 5 , 5 , 5 , 6 , 6 ] b=[5,5,5,5,6,6] b=[5,5,5,5,6,6] and there are 2 2 2 distinct elements — 5 5 5 and 6 6 6.
  • The first cyclic shift of p p p is [ 3 , 5 , 1 , 2 , 4 , 6 ] [3,5,1,2,4,6] [3,5,1,2,4,6]. Its power is 3 3 3 since b = [ 3 , 5 , 5 , 5 , 5 , 6 ] b=[3,5,5,5,5,6] b=[3,5,5,5,5,6].
  • The second cyclic shift of p p p is [ 6 , 3 , 5 , 1 , 2 , 4 ] [6,3,5,1,2,4] [6,3,5,1,2,4]. Its power is 1 1 1 since b = [ 6 , 6 , 6 , 6 , 6 , 6 ] b=[6,6,6,6,6,6] b=[6,6,6,6,6,6].
  • The third cyclic shift of p p p is [ 4 , 6 , 3 , 5 , 1 , 2 ] [4,6,3,5,1,2] [4,6,3,5,1,2]. Its power is 2 2 2 since b = [ 4 , 6 , 6 , 6 , 6 , 6 ] b=[4,6,6,6,6,6] b=[4,6,6,6,6,6].
  • The fourth cyclic shift of p p p is [ 2 , 4 , 6 , 3 , 5 , 1 ] [2,4,6,3,5,1] [2,4,6,3,5,1]. Its power is 3 3 3 since b = [ 2 , 4 , 6 , 6 , 6 , 6 ] b=[2,4,6,6,6,6] b=[2,4,6,6,6,6].
  • The fifth cyclic shift of p p p is [ 1 , 2 , 4 , 6 , 3 , 5 ] [1,2,4,6,3,5] [1,2,4,6,3,5]. Its power is 4 4 4 since b = [ 1 , 2 , 4 , 6 , 6 , 6 ] b=[1,2,4,6,6,6] b=[1,2,4,6,6,6].

Therefore, c = [ 2 , 3 , 1 , 2 , 3 , 4 ] c=[2,3,1,2,3,4] c=[2,3,1,2,3,4].

In the third, fourth, and sixth testcases, we can show that there is no permutation that satisfies array c c c.

题解

思路

首先 c c c 数组中肯定存在 c i = 1 c_i=1 ci=1 ,表示原排列 p p p 经过操作 o p i op_i opi p 0 = n p_0=n p0=n ,且 c i = 1 c_i=1 ci=1 只会出现一次。

我们再看一般情况,假设已知 c i c_i ci ,我们能否确定 c i + 1 c_{i+1} ci+1 呢?答案是肯定的。

我们假设经过 o p i op_i opi 后序列为 p 0 , p 1 , p 2 , . . . , p n − 1 p_0,p_1,p_2,...,p_{n-1} p0,p1,p2,...,pn1 ,我们想要进行操作 o p i + 1 op_{i+1} opi+1 ,实际上就是将我们目前的序列的最后一个数移动到最前面,变为 p n − 1 , p 0 , p 1 , p 2 , . . . , p n − 2 p_{n-1},p_0,p_1,p_2,...,p_{n-2} pn1,p0,p1,p2,...,pn2 ,若 p n − 1 < p 0 p_{n-1} <p_0 pn1p0 c i + 1 = c i + 1 c_{i+1}=c_i+1 ci+1=ci+1 ,否则 c i + 1 ≤ c i c_{i+1}≤c_i ci+1ci ,证明大家意会一下吧,题主表达能力太弱了不知道怎么说呜呜呜。

因此我们直接从 c i = 1 c_i=1 ci=1 开始往后枚举即可。

大家晕的话可以去看 pzr大佬

代码

#include <bits/stdc++.h>

// #define int long long

using namespace std;

constexpr int p = 998244353;
using i64 = long long;

void solve()
{
    int n;
    cin >> n;

    vector<int> c(n);
    for (int i = 0; i < n; i ++ ) cin >> c[i];

    auto it = find(c.begin(), c.end(), 1);
    if (it == c.end()) {
        cout << "NO\n";
        return;
    }

    rotate(c.begin(), it, c.end()); // 又从jls哪里学了个函数

    for (int i = 1; i < n; i ++ ) {
        if (c[i] > c[i - 1] + 1 || c[i] == 1) { // 不能出现两个1
            cout << "NO\n";
            return;
        }
    }
    cout << "YES\n";
}

signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int T;
    cin >> T;

    while (T -- ) {
        solve();
    }

    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值