• [Codeforces] number theory (R1200) Part.9


    [Codeforces] number theory (R1200) Part.9

    题单:https://codeforces.com/problemset/page/6?tags=number%20theory,0-1200

    1533A. Digits Sum

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

    题意

    对整数 x x x,定义 S ( x ) S(x) S(x) x x x的十进制表示的所有数码之和.称一个整数 x x x是好的,如果 S ( x + 1 ) < S ( x ) S(x+1)S(x+1)<S(x).给定一个整数 n n n,求 [ 1 , n ] [1,n] [1,n]中好的数的个数.

    t    ( 1 ≤ t ≤ 1000 ) t\ \ (1\leq t\leq 1000) t  (1t1000)组测试数据.每组测试数据输入一个整数 n    ( 1 ≤ n ≤ 1 e 9 ) n\ \ (1\leq n\leq 1\mathrm{e}9) n  (1n1e9).

    思路

    显然只有以 9 9 9结尾的整数符合条件,问题转化为求 [ 1 , n ] [1,n] [1,n]中以 9 9 9结尾的数的个数. a n s = ⌊ n + 1 10 ⌋ ans=\left\lfloor\dfrac{n+1}{10}\right\rfloor ans=10n+1,即先将 [ 1 , n ] [1,n] [1,n]中的数都 + 1 +1 +1,再考察其中 10 10 10的倍数的个数.

    代码

    void solve() {
    	int n; cin >> n;
      cout << (n + 1) / 10 << endl;
    }
    
    int main() {
    	CaseT  // 单测时注释掉该行
    	solve();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9


    1562B. Scenes From a Memory

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

    题意

    给定一个十进制表示(不含前导零)有 k k k位的正整数 n n n,删除其中的一些数码(不能全部删除)使得剩下的数非素数.

    t    ( 1 ≤ t ≤ 1000 ) t\ \ (1\leq t\leq 1000) t  (1t1000)组测试数据.每组测试数据第一行输入一个整数 k    ( 1 ≤ k ≤ 50 ) k\ \ (1\leq k\leq 50) k  (1k50).第二行输入一个整数 n    ( 1 0 k − 1 ≤ n < 1 0 k ) n\ \ (10^{k-1}\leq n<10^k) n  (10k1n<10k).数据保证所有测试数据的 k k k之和不超过 1 e 4 1\mathrm{e}4 1e4.

    对每组测试数据,先输出留下的数码个数,再输出删除后得到的非素数.数据保证有解,若有多组解,输出任一组.

    思路

    非素数即 1 1 1或偶数.

    ①若 n n n中包含数码 1 , 4 , 6 , 8 , 9 1,4,6,8,9 1,4,6,8,9,显然可只保留这些数码.

    ②若 n n n包含两个相同的数码,则它能被 11 11 11整除,可只保留这两个相同的数码.

    ③若 n n n包含数码 2 2 2 5 5 5且它们不在首位,则只需将它们后面的数码都删除.

    ​ 注意到还可只保留数码 2 2 2 5 5 5及其前面一位,即构造一个两位数的答案.

    ④若上述情况都不满足,因数据保证有解,则 n n n中存在两数码之和是 3 3 3的倍数,

    ​ 则由它们组成的两位数也是 3 3 3的倍数.

    综上, k ≥ 2 k\geq 2 k2时,恒存在一个两位数的答案.

    预处理出两位数的素数,枚举 n n n中剩下的两个数码即可,时间复杂度 O ( k 2 ) O(k^2) O(k2),所有测试数据的 k k k之和不超过 1 e 4 1\mathrm{e}4 1e4,可过.

    代码

    const int MAXN = 105;
    bool prime[MAXN];
    
    void init() {
      for (int i = 2; i < MAXN; i++) {
        prime[i] = true;
        for (int j = 2; j * j <= i; j++) 
          if (i % j == 0) prime[i] = false;
      }
    }
    
    void get(int n, string s) {
      for (auto ch : s) {
        if (ch == '1' || ch == '4' || ch == '6' || ch == '8' || ch == '9') {
          cout << 1 << endl << ch << endl;
          return;
        }
      }
    
      for (int i = 0; i < n; i++) {
        for (int j = i + 1; j < n; j++) {
          int tmp = (s[i] - '0') * 10 + s[j] - '0';
          if (!prime[tmp]) {
            cout << 2 << endl << tmp << endl;
            return;
          }
        }
      }
    }
    
    void solve() {
    	init();
    
      CaseT{
        int n; string s; cin >> n >> s;
        get(n, s);
      }
    }
    
    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
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42


    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


    1583A. Windblume Ode

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

    题意

    给定一个包含 n n n个相异元素的序列 a 1 , ⋯   , a n a_1,\cdots,a_n a1,,an,从其中选出最多个元素,使得它们之和非素数,输出选择的元素的个数和下标.可以证明必有解.

    t    ( 1 ≤ t ≤ 100 ) t\ \ (1\leq t\leq 100) t  (1t100)组测试数据.每组测试数据第一行输入一个整数 n    ( 3 ≤ n ≤ 100 ) n\ \ (3\leq n\leq 100) n  (3n100).第二行输入 n n n个相异的整数 a 1 , ⋯   , a n    ( 1 ≤ a i ≤ 200 ) a_1,\cdots,a_n\ \ (1\leq a_i\leq 200) a1,,an  (1ai200).

    思路

    (1) a i    ( 1 ≤ i ≤ n ) a_i\ \ (1\leq i\leq n) ai  (1in)都为偶数时,显然它们之和是 > 2 >2 >2的偶数,取整个序列即可.

    (2) a i    ( 1 ≤ i ≤ n ) a_i\ \ (1\leq i\leq n) ai  (1in)不全为偶数时,至少存在一个奇数.

    ​ ①若所有元素之和为偶数,显然该偶数 > 2 >2 >2,取整个序列即可.

    ​ ②若所有元素之和为奇数,减去一个奇数将其转化为情况①,显然得到的偶数 > 2 >2 >2.

    代码

    bool check(int x) {  // 判断x是否是素数
    	if (x <= 2) return x == 2;
    	
    	for (int i = 2; i <= sqrt(x); i++)
    		if (x % i == 0) return false;
    	return true;
    }
    
    void solve() {
    	int n; cin >> n;
    	vi a(n + 1);
    	int odd = -1;  // 奇数的下标
    	int sum = 0;  // 元素之和
    	for (int i = 1; i <= n; i++) {
    		cin >> a[i];
    		sum += a[i];
    		if (odd == -1 && a[i] & 1) odd = i;
    	}
    
    	if (check(sum)) {
    		cout << n - 1 << endl;
    		for (int i = 1; i <= n; i++)
    			if (i != odd) cout << i << ' ';
    		cout << endl;
    	}
    	else {
    		cout << n << endl;
    		for (int i = 1; i <= n; i++) cout << i << ' ';
    		cout << endl;
    	}
    }
    
    int main() {
    	CaseT  // 单测时注释掉该行
    	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
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36


    1593D1. All are Same

    原题指路:https://codeforces.com/problemset/problem/1593/D1

    题意

    给定一个长度为 n n n的序列 a 1 , ⋯   , a n a_1,\cdots,a_n a1,,an,选定一个正整数 k k k,每次操作选择一个下标 i    ( 1 ≤ i ≤ n ) i\ \ (1\leq i\leq n) i  (1in),令 a i − = k a_i-=k ai=k.经若干次(可能为零次)操作后序列中所有元素相等,求 k k k的最大值.若 k k k可任意大,输出 − 1 -1 1.

    t    ( 1 ≤ t ≤ 10 ) t\ \ (1\leq t\leq 10) t  (1t10)组测试数据.每组测试数据第一行输入一个偶数 n    ( 4 ≤ n ≤ 40 ) n\ \ (4\leq n\leq 40) n  (4n40).第二行输入 n n n个整数 a 1 , ⋯   , a n    ( − 1 e 6 ≤ a i ≤ 1 e 6 ) a_1,\cdots,a_n\ \ (-1\mathrm{e}6\leq a_i\leq 1\mathrm{e}6) a1,,an  (1e6ai1e6).数据保证所有测试数据的 n n n之和不超过 100 100 100.

    思路

    ①若序列中所有元素相等,显然 k k k可任意大.

    ②若序列中元素不全相等,设 a m i n a_{min} amin是序列中最小的元素,显然 k = gcd ⁡ 1 ≤ i ≤ n ( a i − a m i n ) \displaystyle k=\gcd_{1\leq i\leq n} (a_i-a_{min}) k=1ingcd(aiamin).

    代码

    void solve() {
    	int n; cin >> n;
    	vi a(n);
    	bool different = false;  // 记录序列a[]是否所有元素都相等
    	int minnum = INF;
    	for (int i = 0; i < n; i++) {
    		cin >> a[i];
    		minnum = min(minnum, a[i]);
    		different |= a[i] != a[0];
    	}
    
    	if (!different) cout << -1 << endl;
    	else {
    		int ans = 0;
    		for (int i = 0; i < n; i++) ans = gcd(ans, a[i] - minnum);
    		cout << ans << endl;
    	}
    }
    
    int main() {
    	CaseT  // 单测时注释掉该行
    	solve();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23


    1605A. A.M. Deviation

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

    题意

    对三个整数 a 1 , a 2 , a 3 a_1,a_2,a_3 a1,a2,a3,定义它们的算术平均偏差 d ( a 1 , a 2 , a 3 ) = ∣ a 1 + a 3 − 2 a 2 ∣ d(a_1,a_2,a_3)=|a_1+a_3-2a_2| d(a1,a2,a3)=a1+a32a2.现有操作:选择两个下标 i , j    ( i , j ∈ { 1 , 2 , 3 } , i ≠ j ) i,j\ \ (i,j\in\{1,2,3\},i\neq j) i,j  (i,j{1,2,3},i=j),令 a i + + , a j − − a_i++,a_j-- ai++,aj.求经过若干次(可能为零次)操作后 d ( a 1 , a 2 , a 3 ) d(a_1,a_2,a_3) d(a1,a2,a3)的最小值.

    t    ( 1 ≤ t ≤ 5000 ) t\ \ (1\leq t\leq 5000) t  (1t5000)组测试数据.每组测试数据输入三个整数 a 1 , a 2 , a 3    ( 1 ≤ a 1 , a 2 , a 3 ≤ 1 e 8 ) a_1,a_2,a_3\ \ (1\leq a_1,a_2,a_3\leq 1\mathrm{e}8) a1,a2,a3  (1a1,a2,a31e8).

    思路

    ①令 a 1 + + , a 3 − − a_1++,a_3-- a1++,a3或令 a 3 + + , a 1 − − a_3++,a_1-- a3++,a1都不改变 d ( a 1 , a 2 , a 3 ) d(a_1,a_2,a_3) d(a1,a2,a3).

    ②令 a 1 ( a 3 ) + + , a 2 − − a_1(a_3)++,a_2-- a1(a3)++,a2会使得 d ( a 1 , a 2 , a 3 ) + 3 d(a_1,a_2,a_3)+3 d(a1,a2,a3)+3.

    ③令 a 1 ( a 3 ) − − , a 2 + + a_1(a_3)--,a_2++ a1(a3),a2++会使得 d ( a 1 , a 2 , a 3 ) − 3 d(a_1,a_2,a_3)-3 d(a1,a2,a3)3.

    注意到若加减 3 3 3的倍数次,则 d ( a 1 , a 2 , a 3 ) d(a_1,a_2,a_3) d(a1,a2,a3)的值在模 3 3 3意义下不变:

    ①若 d ( a 1 , a 2 , a 3 ) ≡ 0    ( m o d   3 ) d(a_1,a_2,a_3)\equiv 0\ \ (\mathrm{mod}\ 3) d(a1,a2,a3)0  (mod 3),则 d ( a 1 , a 2 , a 3 ) d(a_1,a_2,a_3) d(a1,a2,a3)的最小值为 ∣ 0 ∣ = 0 |0|=0 ∣0∣=0.

    ②若 d ( a 1 , a 2 , a 3 ) ≡ 1    ( m o d   3 ) d(a_1,a_2,a_3)\equiv 1\ \ (\mathrm{mod}\ 3) d(a1,a2,a3)1  (mod 3),则 d ( a 1 , a 2 , a 3 ) d(a_1,a_2,a_3) d(a1,a2,a3)的最小值为 ∣ 1 ∣ = 1 |1|=1 ∣1∣=1.

    ③若 d ( a 1 , a 2 , a 3 ) ≡ 2    ( m o d   3 ) d(a_1,a_2,a_3)\equiv 2\ \ (\mathrm{mod}\ 3) d(a1,a2,a3)2  (mod 3),则 d ( a 1 , a 2 , a 3 ) d(a_1,a_2,a_3) d(a1,a2,a3)的最小值为 ∣ 2 − 3 ∣ = 1 |2-3|=1 ∣23∣=1.

    综上,若初始时 d ( a 1 , a 2 , a 3 ) d(a_1,a_2,a_3) d(a1,a2,a3) 3 3 3的倍数,则 a n s = 0 ans=0 ans=0;否则 a n s = 1 ans=1 ans=1.

    代码

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


    1609A. Divide and Multiply

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

    题意

    给定一个长度为 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_i ai 2 2 2的倍数,令 a i / = 2 , a j ∗ = 2 a_i/=2,a_j*=2 ai/=2,aj=2.求经若干次(可能为零次)操作后序列元素之和的最大值.

    t    ( 1 ≤ t ≤ 1 e 4 ) t\ \ (1\leq t\leq 1\mathrm{e}4) t  (1t1e4)组测试数据.每组测试数据第一行输入一个整数 n    ( 1 ≤ n ≤ 15 ) n\ \ (1\leq n\leq 15) n  (1n15).第二行输入 n n n个整数 a 1 , ⋯   , a n    ( 1 ≤ a i < 16 ) a_1,\cdots,a_n\ \ (1\leq a_i<16) a1,,an  (1ai<16).

    思路

    显然应让 a [ ] a[] a[]中最大的数乘尽量多次 2 2 2,能乘的最大次数即其他元素能整除 2 2 2的最大次数.

    代码

    void solve() {
    	int n; cin >> n;
    	vl a(n);
    	int s = 0;  // 除以2的次数
    	for (auto& ai : a) {
    		cin >> ai;
    		while (ai % 2 == 0) {
    			ai >>= 1;
    			s++;
    		}
    	}
    
    	sort(all(a), greater());
    	a[0] *= ((ll)1 << s);
      
    	ll sum = 0;
    	for (int i = 0; i < n; i++) sum += a[i];
    	cout << sum << endl;
    }
    
    int main() {
    	CaseT  // 单测时注释掉该行
    	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


    1617B. GCD Problem

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

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

    给定一个正整数 n n n,求三个相异的正整数 a , b , c   s . t .   a + b + c = n , gcd ⁡ ( a , b ) = c a,b,c\ s.t.\ a+b+c=n,\gcd(a,b)=c a,b,c s.t. a+b+c=n,gcd(a,b)=c.

    t    ( 1 ≤ t ≤ 1 e 5 ) t\ \ (1\leq t\leq 1\mathrm{e}5) t  (1t1e5)组测试数据.每组测试数据输入一个整数 n    ( 10 ≤ n ≤ 1 e 9 ) n\ \ (10\leq n\leq 1\mathrm{e}9) n  (10n1e9).

    思路I

    注意到 n ≥ 10 n\geq 10 n10时,固定 c = 1 c=1 c=1必有解.

    枚举 a = 2 , 3 , ⋯ a=2,3,\cdots a=2,3,,对每个 a a a,令 b = n − a − 1 b=n-a-1 b=na1,检查 gcd ⁡ ( a , b ) = 1 \gcd(a,b)=1 gcd(a,b)=1是否成立.该方法不会超时是因为至少存在一个素数 p ≤ 29   s . t .   p ∤ ( n − 1 ) p\leq 29\ s.t.\ p\not\mid (n-1) p29 s.t. p(n1).

    代码I

    void solve() {
    	int n; cin >> n;
    	
    	for (int a = 2;; a++) {
    		int b = n - a - 1;
    		if (a != b && gcd(a, b) == 1) {
    			cout << a << ' ' << b << ' ' << 1 << endl;
    			return;
    		}
    	}
    }
    
    int main() {
    	CaseT  // 单测时注释掉该行
    	solve();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    思路II

    随机 a a a的值,其余同思路I.

    代码II

    mt19937 rng(time(0));
    
    void solve() {
    	int n; cin >> n;
    	
    	while (true) {
    		int a = uniform_int_distribution(2, n - 2)(rng);
    		int b = n - a - 1;
    		if (a != 1 && b != 1 && a != b && gcd(a, b) == 1) {
    			cout << a << ' ' << b << ' ' << 1 << endl;
    			return;
    		}
    	}
    }
    
    int main() {
    	CaseT  // 单测时注释掉该行
    	solve();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    思路III

    构造:

    n ≡ 0    ( m o d   2 ) n\equiv 0\ \ (\mathrm{mod}\ 2) n0  (mod 2)时,取 ( a , b , c ) = ( n − 3 , 2 , 1 ) (a,b,c)=(n-3,2,1) (a,b,c)=(n3,2,1).

    n ≡ 1    ( m o d   4 ) n\equiv 1\ \ (\mathrm{mod}\ 4) n1  (mod 4)时,取 ( a , b , c ) = ( ⌊ n 2 ⌋ − 1 , ⌊ n 2 ⌋ + 1 , 1 ) (a,b,c)=\left(\left\lfloor\dfrac{n}{2}\right\rfloor-1,\left\lfloor\dfrac{n}{2}\right\rfloor+1,1\right) (a,b,c)=(2n1,2n+1,1).

    n ≡ 3    ( m o d   4 ) n\equiv 3\ \ (\mathrm{mod}\ 4) n3  (mod 4)时,取 ( a , b , c ) = ( ⌊ n 2 ⌋ − 2 , ⌊ n 2 ⌋ + 2 , 1 ) (a,b,c)=\left(\left\lfloor\dfrac{n}{2}\right\rfloor-2,\left\lfloor\dfrac{n}{2}\right\rfloor+2,1\right) (a,b,c)=(2n2,2n+2,1).

    代码III

    void solve() {
    	int n; cin >> n;
    	
    	if (n % 2 == 0) cout << n - 3 << ' ' << 2 << ' ' << 1 << endl;
    	else if (n % 4 == 1) cout << n / 2 - 1 << ' ' << n / 2 + 1 << ' ' << 1 << endl;
    	else cout << n / 2 - 2 << ' ' << n / 2 + 2 << ' ' << 1 << endl;
    }
    
    int main() {
    	CaseT  // 单测时注释掉该行
    	solve();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12


    1629B. GCD Arrays

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

    题意

    给定两整数 l , r l,r l,r,定义序列 a [ ] a[] a[] l , l + 1 , ⋯   , r l,l+1,\cdots, r l,l+1,,r.现有操作:选择 a a a中的两元素,将它们的替换为它们之积.问至多 k k k次操作后能否使得序列的所有元素的 gcd ⁡ > 1 \gcd>1 gcd>1,若能则输出"YES";否则输出"NO".

    t    ( 1 ≤ t ≤ 1 e 5 ) t\ \ (1\leq t\leq 1\mathrm{e}5) t  (1t1e5)组测试数据.每组测试数据输入三个整数 l , r , k    ( 1 ≤ l ≤ r ≤ 1 e 9 , 0 ≤ k ≤ r − 1 ) l,r,k\ \ (1\leq l\leq r\leq 1\mathrm{e}9,0\leq k\leq r-1) l,r,k  (1lr1e9,0kr1).

    思路

    显然每次操作可合并两个数的素因子.为使得所有元素的 gcd ⁡ > 1 \gcd>1 gcd>1且步数尽量少,因序列 a [ ] a[] a[]是连续整数,故取 gcd ⁡ = 2 \gcd=2 gcd=2最优,所需的最少步数为序列中奇数的个数,即序列长度 − - 序列中偶数的个数,具体地, s t e p = ( r − l + 1 ) − ( ⌊ r 2 ⌋ − ⌊ l − 1 2 ⌋ ) step=(r-l+1)-\left(\left\lfloor\dfrac{r}{2}\right\rfloor-\left\lfloor\dfrac{l-1}{2}\right\rfloor\right) step=(rl+1)(2r2l1).

    注意特判 l = r l=r l=r的情况,此时若 l = r = 1 l=r=1 l=r=1,答案为"NO";否则答案为"YES";

    代码

    void solve() {
    	int l, r, k; cin >> l >> r >> k;
    	
    	if (l == r) cout << (l == 1 ? "NO" : "YES") << endl;
    	else {
    		int ans = (r - l + 1) - (r / 2 - (l - 1) / 2);
    		cout << (k >= ans ? "YES" : "NO") << endl;
    	}
    }
    
    int main() {
    	CaseT  // 单测时注释掉该行
    	solve();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14


    1656C. Make Equal With Mod

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

    题意

    给定一个长度为 n n n的序列 a 1 , ⋯   , a n a_1,\cdots,a_n a1,,an.现有操作:选定一个整数 x ≥ 2 x\geq 2 x2,将所有 a i % = x    ( 1 ≤ i ≤ n ) a_i\%=x\ \ (1\leq i\leq n) ai%=x  (1in).问若干次(可能为零次)操作后是否能使得序列中所有元素相等,若能则输出"YES";否则输出"NO".

    t    ( 1 ≤ t ≤ 1 e 4 ) t\ \ (1\leq t\leq 1\mathrm{e}4) t  (1t1e4)组测试数据.每组测试数据第一行输入一个整数 n    ( 1 ≤ n ≤ 1 e 5 ) n\ \ (1\leq n\leq 1\mathrm{e}5) n  (1n1e5).第二行输入 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.

    思路

    ①若序列中不存在 1 1 1,则每次取 x = max ⁡ 1 ≤ i ≤ n a i \displaystyle x=\max_{1\leq i\leq n}a_i x=1inmaxai,即每次将序列中的最大值置为 0 0 0,答案为"YES".

    ②若序列中存在 1 1 1且不存在相邻的两数 m , m + 1 m,m+1 m,m+1,则每次取 x = max ⁡ 1 ≤ i ≤ n a i − 1 \displaystyle x=\max_{1\leq i\leq n}a_i-1 x=1inmaxai1,

    ​ 最终将所有元素变为都是 1 1 1,答案为"YES".

    ③若序列中存在 1 1 1且存在相邻的两数 m , m + 1 m,m+1 m,m+1,则将其中一个数变为 1 1 1时会使得另一个数变为 0 0 0,

    ​ 故无法将所有元素变为都相等,答案为"NO".

    代码

    int main() {
    	CaseT{
    		int n; cin >> n;
    		vi a(n);
    		bool same = true;  // 记录是否所有元素都相等
    		for (int i = 0; i < n; i++) {
    			cin >> a[i];
    			if (a[i] != a[0]) same = false;
    		}
    
    		if (same || n == 1) {
    			cout << "YES" << endl;
    			continue;
    		}
    		
    		sort(a.begin(), a.end());
    		
    		bool one = false;  // 记录数组中是否有1
    		bool adjancent = false;  // 记录数组中是否有相邻的数
    		for (int i = 0; i < n; i++) {
    			if (a[i] == 1) one = true;
    			if (i < n - 1 && a[i] + 1 == a[i + 1]) adjancent = true;
    		}
    		cout << ((one && adjancent) ? "NO" : "YES") << endl;
    	}
    }
    
    • 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


  • 相关阅读:
    昆仑芯 AI 加速卡 R200 与龙蜥操作系统完成产品兼容认证
    Docker背后的标准化容器执行引擎——runC
    python系列教程216——何时用列表解析
    102.二叉树的层序遍历
    联机算法和脱机算法[Alg_001]
    单元测试实战(二)Service 的测试
    Node-RED系列教程-22node-red操作modbusRTU
    c++单例模式线程安全几种实现方式
    C# 守护进程的介绍及实现
    《天天数学》连载53:二月二十二日
  • 原文地址:https://blog.csdn.net/Hytidel/article/details/126861311