• [Codeforces] combinatorics (R1200) Part.2


    [Codeforces] combinatorics (R1200) Part.2

    题单:https://codeforces.com/problemset?tags=combinatorics,0-1200

    1543B. Customising the Track

    原题指路:https://codeforces.com/problemset/problem/1543/B

    题意

    给定一个长度为 n n n的序列 a 1 , ⋯   , a n a_1,\cdots,a_n a1,,an.现有操作:选择两个下标 i , j    ( 1 ≤ i , j ≤ n , i ≠ j ) i,j\ \ (1\leq i,j\leq n,i\neq j) i,j  (1i,jn,i=j),令 a i − − , a j + + a_i--,a_j++ ai,aj++.求经过若干次(可能为 0 0 0次)操作后 ∑ i = 1 n ∑ j = i + 1 n ∣ a i − a j ∣ \displaystyle\sum_{i=1}^n \sum_{j=i+1}^n |a_i-a_j| i=1nj=i+1naiaj的最小值.

    t    ( 1 ≤ t ≤ 1 e 4 ) t\ \ (1\leq t\leq 1\mathrm{e}4) t  (1t1e4)组测试数据.每组测试数据第一行输入一个整数 n    ( 1 ≤ n ≤ 2 e 5 ) n\ \ (1\leq n\leq 2\mathrm{e}5) n  (1n2e5).第二行输入 n n n个整数 a 1 , ⋯   , a n    ( 0 ≤ a i ≤ 1 e 9 ) a_1,\cdots,a_n\ \ (0\leq a_i\leq 1\mathrm{e}9) a1,,an  (0ai1e9).数据保证所有测试数据的 n n n之和不超过 2 e 5 2\mathrm{e}5 2e5.

    思路

    a n s = ∑ i = 1 n ∑ j = i + 1 n ∣ a i − a j ∣ \displaystyle ans=\sum_{i=1}^n \sum_{j=i+1}^n |a_i-a_j| ans=i=1nj=i+1naiaj描述序列 a [ ] a[] a[]的波动情况,欲使其最小,应尽量让 a [ ] a[] a[]均匀分布.设 a [ ] a[] a[]中元素之和为 s u m sum sum,则 n n n个元素每个先分 ⌊ s u m n ⌋ \left\lfloor\dfrac{sum}{n}\right\rfloor nsum,这一部分不会对 a n s ans ans有贡献.剩下的 s u m % n sum\% n sum%n放在前 s u m % n sum\% n sum%n个元素上,此时前 s u m % n sum\% n sum%n个为 1 1 1的元素会与后面的 ( n − s u m % n ) (n-sum\% n) (nsum%n)个为 0 0 0的元素每对产生 1 1 1点贡献,故 a n s = ( s u m % n ) ( n − s u m % n ) ans=(sum\% n)(n-sum\% n) ans=(sum%n)(nsum%n).

    代码

    void solve() {
    	int n; cin >> n;
        ll sum = 0;
        for (int i = 0; i < n; i++) {
            int a; cin >> a;
            sum += a;
        }
    
        cout << (ll)(sum % n) * (n - sum % n) << endl;
    } 
    
    int main() {
    	CaseT  // 单测时注释掉该行
    	solve();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15


    1574B. Combinatorics Homework

    原题指路:https://codeforces.com/problemset/problem/1574/B

    题意 ( 2   s 2\ \mathrm{s} 2 s)

    给定四个整数 a , b , c , m a,b,c,m a,b,c,m,判断是否存在满足下列条件的字符串:①包含 a a a个字符’A’, b b b个字符’B’, c c c个字符’C’;②不存在其他字符;③有恰好 m m m对相邻相同的字符,若存在则输出"YES";否则输出"NO".

    t    ( 1 ≤ t ≤ 1 e 4 ) t\ \ (1\leq t\leq 1\mathrm{e}4) t  (1t1e4)组测试数据.每组测试数据输入四个整数 a , b , c , m    ( 1 ≤ a , b , c ≤ 1 e 8 , 0 ≤ m ≤ 1 e 8 ) a,b,c,m\ \ (1\leq a,b,c\leq 1\mathrm{e}8,0\leq m\leq 1\mathrm{e}8) a,b,c,m  (1a,b,c1e8,0m1e8).

    思路

    考虑对给定的 a , b , c a,b,c a,b,c,求合法的 m m m的范围.

    ①最大值:显然将所有’A’、‘B’、'C’分别放一起时取得最大值,此时 m = ( a − 1 ) + ( b − 1 ) + ( c − 1 ) = a + b + c − 3 m=(a-1)+(b-1)+(c-1)=a+b+c-3 m=(a1)+(b1)+(c1)=a+b+c3.

    ②最小值:因字符’A’、‘B’、'C’地位等价,不妨设 a ≤ b ≤ c a\leq b\leq c abc.

    ​ 考虑构造"CACACA…CBCBCB…CCC…"的字符串,即用 ( a + b ) (a+b) (a+b)个字符’C’隔开相邻的’A’和’B’,

    ​ 此时剩下的 c − ( a + b ) c-(a+b) c(a+b)个字符’C’会组成 ( c − a − b − 1 ) (c-a-b-1) (cab1)对相邻相同的字符.

    综上, m ∈ [ c − a − b − 1 , a + b + c − 3 ] m\in[c-a-b-1,a+b+c-3] m[cab1,a+b+c3].

    m m m可取到 [ c − a − b − 1 , a + b + c − 3 ] [c-a-b-1,a+b+c-3] [cab1,a+b+c3]中的任意整数.

    [] 当 m > 0 m>0 m>0时,取走一个出现次数最多的字符,并使得 m − − m-- m,直至 m = 0 m=0 m=0.

    考虑将取走的字符放回 m = 0 m=0 m=0的字符串中对应字符最后一次出现的位置之后,

    ​ 显然这样使得该字符的出现次数 + + ++ ++,同时 m + + m++ m++.

    代码

    void solve() {
    	int tmpa, tmpb, tmpc, m; cin >> tmpa >> tmpb >> tmpc >> m;
    
       int a = min({tmpa, tmpb, tmpc}), c = max({tmpa, tmpb, tmpc}), b = tmpa + tmpb + tmpc - a - c;
       int low = c - a - b - 1, high = a + b + c - 3;
       cout << (low <= m && m <= high ? "YES" : "NO") << endl;
    } 
    
    int main() {
    	CaseT  // 单测时注释掉该行
    	solve();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12


    1581A. CQXYM Count Permutations

    原题指路:https://codeforces.com/problemset/problem/1581/A

    题意

    求满足如下条件的长度为 2 n 2n 2n 1 ∼ 2 n 1\sim 2n 12n的排列的个数,答案对 1 e 9 + 7 1\mathrm{e}9+7 1e9+7取模:满足 p i < p i + 1 p_ipi<pi+1的下标 i i i的个数不少于 n n n.

    t t t组测试数据.每组测试数据输入一个整数 n    ( 1 ≤ n ≤ 1 e 5 ) n\ \ (1\leq n\leq 1\mathrm{e}5) n  (1n1e5).数据保证所有测试数据的 n n n之和不超过 1 e 5 1\mathrm{e}5 1e5.

    思路

    称一个排列的值为满足 p i < p i + 1 p_ipi<pi+1的下标 i i i的个数.将一个值为 i i i的排列倒序可得值为 ( 2 n − i ) (2n-i) (2ni)的排列,则所有值 < n <n的排列构成的集合与所有值 ≤ n \leq n n的排列构成的集合间存在双射,则答案为每个集合的大小,即 a n s = 1 2 ⋅ ( 2 n ) ! ans=\dfrac{1}{2}\cdot (2n)! ans=21(2n)!.

    代码

    const int MAXN = 2e5 + 5;
    const int MOD = 1e9 + 7;
    int fac[MAXN], ifac[MAXN];
    
    void init() {
      fac[0] = 1;
      for (int i = 1; i < MAXN; i++) fac[i] = (ll)fac[i - 1] * i % MOD;
      ifac[MAXN - 1] = qpow(fac[MAXN - 1], MOD - 2, MOD);
      for (int i = MAXN - 1; i; i--) ifac[i - 1] = (ll)ifac[i] * i % MOD;
    }
    
    void solve() {
    	init();
    
      CaseT {
        int n; cin >> n;
        cout << (ll)fac[2 * n] * qpow(2, MOD - 2, MOD) % MOD << endl;
      }
    } 
    
    int main() {
    	solve();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23


    1582B. Luntik and Subsequences

    原题指路:https://codeforces.com/problemset/problem/1582/B

    题意

    给定一个长度为 n n n的序列 a 1 , ⋯   , a n a_1,\cdots,a_n a1,,an,令 s = ∑ i = 1 n a i \displaystyle s=\sum_{i=1}^n a_i s=i=1nai.称 a [ ] a[] a[]的一个非空子列是好的,如果其中的元素之和为 s − 1 s-1 s1,求 a [ ] a[] a[]的非空子列中好的子列的个数.

    t    ( 1 ≤ t ≤ 1000 ) t\ \ (1\leq t\leq 1000) t  (1t1000)组测试数据.每组测试数据第一行输入一个整数 n    ( 1 ≤ n ≤ 60 ) n\ \ (1\leq n\leq 60) n  (1n60).第二行输入 n n n个整数 a 1 , ⋯   , a n    ( 0 ≤ a i ≤ 1 e 9 ) a_1,\cdots,a_n\ \ (0\leq a_i\leq 1\mathrm{e}9) a1,,an  (0ai1e9).

    思路

    先不考虑 a [ ] a[] a[]中值为 0 0 0的元素,显然一个子列是好的当且仅当它是 a [ ] a[] a[]删除一个值为 1 1 1的元素得到的子列,而值为 0 0 0的元素可删可不删,设值为 0 0 0 1 1 1的元素的个数分别为 c n t 0 cnt_0 cnt0 c n t 1 cnt_1 cnt1,则 a n s = c n t 1 ⋅ 2 c n t 0 ans=cnt_1\cdot 2^{cnt_0} ans=cnt12cnt0.

    代码

    void solve() {
    	int n; cin >> n;
      int cnt0 = 0, cnt1 = 0;
      vi a(n);
      for (auto& ai : a) {
        cin >> ai;
        cnt0 += ai == 0, cnt1 += ai == 1;
      }
    
      cout << (ll)cnt1 * ((ll)1 << cnt0) << endl;
    } 
    
    int main() {
    	CaseT  // 单测时注释掉该行
    	solve();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16


    1658B. Marin and Anti-coprime Permutation

    原题指路:https://codeforces.com/problemset/problem/1658/B

    题意

    定义一个长度为 n n n的排列 p 1 , ⋯   , p n p_1,\cdots,p_n p1,,pn是好的,如果 gcd ⁡ ( 1 ⋅ p 1 , 2 ⋅ p 2 , ⋯   , n ⋅ p n ) > 1 \gcd(1\cdot p_1,2\cdot p_2,\cdots,n\cdot p_n)>1 gcd(1p1,2p2,,npn)>1.求 1 ∼ n 1\sim n 1n的排列中好的排列的个数,答案对 998244353 998244353 998244353取模.

    t    ( 1 ≤ t ≤ 1000 ) t\ \ (1\leq t\leq 1000) t  (1t1000)组测试数据.每组测试数据输入一个 n    ( 1 ≤ n ≤ 1000 ) n\ \ (1\leq n\leq 1000) n  (1n1000).

    思路

    g = gcd ⁡ ( 1 ⋅ p 1 , 2 ⋅ p 2 , ⋯   , n ⋅ p n ) g=\gcd(1\cdot p_1,2\cdot p_2,\cdots,n\cdot p_n) g=gcd(1p1,2p2,,npn),则 g ≤ 2 g\leq 2 g2.

    [] ① g > 2 g>2 g>2时,若 ∃ \exists 素数 p > 2   s . t .   p ∣ g p>2\ s.t.\ p\mid g p>2 s.t. pg,因 1 ∼ n 1\sim n 1n中有 ⌊ n p ⌋ \left\lfloor\dfrac{n}{p}\right\rfloor pn p p p的倍数,则至多能匹配 2 ⌊ n p ⌋ < n 2\left\lfloor\dfrac{n}{p}\right\rfloor2pn<n个数.

    g ≤ 2 g\leq 2 g2时,可将值为奇数的数放在偶数下标的位置,将值为偶数的数放在奇数下标的位置. 1 ∼ n 1\sim n 1n中有 n 2 \dfrac{n}{2} 2n个奇数和 n 2 \dfrac{n}{2} 2n个偶数,故 a n s = [ ( n 2 ) ! ] 2 ans=\left[\left(\dfrac{n}{2}\right)!\right]^2 ans=[(2n)!]2.

    代码

    const int MAXN = 1005;
    const int MOD = 998244353;
    int fac[MAXN], ifac[MAXN];
    
    void init() {
      fac[0] = 1;
      for (int i = 1; i < MAXN; i++) fac[i] = (ll)fac[i - 1] * i % MOD;
      ifac[MAXN - 1] = qpow(fac[MAXN - 1], MOD - 2, MOD);
      for (int i = MAXN - 1; i; i--) ifac[i - 1] = (ll)ifac[i] * i % MOD;
    }
    
    void solve() {
    	init();
    
      CaseT {
        int n; cin >> n;
        cout << (n & 1 ? 0 : (ll)fac[n / 2] * fac[n / 2] % MOD) << endl;
      }
    } 
    
    int main() {
    	solve();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23


    1674B. Dictionary

    原题指路:https://codeforces.com/problemset/problem/1674/B

    题意 ( 2   s ) (2\ \mathrm{s}) (2 s)

    将两相异的小写英文字母组成一个单词,将所有单词按字典序排序,下标从 1 1 1开始.给定一个单词,求其下标.

    t    ( 1 ≤ t ≤ 650 ) t\ \ (1\leq t\leq 650) t  (1t650)组测试数据.每组测试数据输入一个长度为 2 2 2的、只包含两相异的小写英文字母的单词.

    思路

    预处理出所有单词即可.

    代码

    umap mp;
    
    void init() {
      for (char fi = 'a'; fi <= 'z'; fi++) {
        for (char se = 'a'; se <= 'z'; se++) {
          if (fi == se) continue;
    
          string word(2, ' ');
          word[0] = fi, word[1] = se;
          mp[word] = mp.size() + 1;
        }
      }
    }
    
    void solve() {
    	init();
    
      CaseT{
        string s; cin >> s;
        cout << mp[s] << endl;
      }
    } 
    
    int main() {
    	solve();
    }
    
    • 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


    1674C. Infinite Replacement

    原题指路:https://codeforces.com/problemset/problem/1674/C

    题意 ( 2   s 2\ \mathrm{s} 2 s)

    给定一个只包含字符’a’的字符串 s s s和只包含小写英文字母的字符串 t t t.现有操作:将 s s s中的一个字符’a’替换为字符串 t t t.求若干次(含零次)操作后能得到的不同字符串的数量.

    t    ( 1 ≤ t ≤ 1 e 4 ) t\ \ (1\leq t\leq 1\mathrm{e}4) t  (1t1e4)组测试数据.每组测试数据第一行输入长度不超过 50 50 50的只包含字符’a’的字符串 s s s.第二行输入长度不超过 50 50 50的只包含小写英文字母的字符串 t t t.

    对每组测试数据,若能得到无穷多种的不同字符串,输出 − 1 -1 1;否则输出能得到的不同字符串的数量.

    思路

    ①若 t t t为"a",则操作后不改变原串, a n s = 1 ans=1 ans=1.

    ②若 t t t的长度 ≥ 2 \geq 2 2且包含字符’a’,则每次操作后 s s s中’a’的数量不减, a n s = I N F ans=INF ans=INF.

    ③若 t t t的长度 ≥ 2 \geq 2 2且不包含字符’a’,则每次操作后 s s s中’a’的数量 − 1 -1 1.

    s s s中每个字符’a’都可选择替换或不替换, a n s = 2 l e n ans=2^{len} ans=2len,其中 l e n len len s s s的长度.

    代码

    void solve() {
    	string s, t; cin >> s >> t;
    
      if (t == "a") cout << 1 << endl;
      else {
        bool ok = false;
        for (auto ch : t) ok |= ch == 'a';
    
        if (ok) cout << -1 << endl;
        else cout << ((ll)1 << s.length()) << endl;
      }
    } 
    
    int main() {
    	CaseT  // 单测时注释掉该行
    	solve();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17


    截至2022.09.14,无新题目

  • 相关阅读:
    SpringBoot+Vue+Element-UI实现鞋类秒杀商城
    CSS3 网格布局
    【微信小程序】分包
    stm32之智能小车总结
    每天一个数据分析题(三百九十九)- 逻辑回归
    springboot+skywalking初体检
    linux系统安装Mysql 快捷方式
    【MySQL】:高效利用MySQL函数实用指南
    多功能电力仪表在物联网的应用
    FastRCNN
  • 原文地址:https://blog.csdn.net/Hytidel/article/details/126847383