首页 > 其他分享 >CSP-S 模拟赛 37

CSP-S 模拟赛 37

时间:2024-10-11 21:21:25浏览次数:8  
标签:int 37 long ans fac define CSP 模拟 mod

CSP-S 模拟赛 37

T1

口胡题。显然尽量靠近中间更优,且选端点一定不劣,于是依据结论将中点设为所有端点的中位数。

代码:

#include <bits/stdc++.h>
#define N 300005
#define int long long
using namespace std;
int n;
int l[N], r[N];
int rk[N << 1];
int pos[N];
int ans;
signed main() {
	freopen("case.in", "r", stdin);
	freopen("case.out", "w", stdout);
	ios::sync_with_stdio(0);
	cin.tie(0);
	cin >> n;
	for (int i = 1; i <= n; i++)
		cin >> l[i] >> r[i], rk[i] = l[i], rk[i + n] = r[i];
	sort(rk + 1, rk + 1 + (n << 1));
	int x = rk[n];
	for (int i = 1; i <= n; i++) {
		if (l[i] <= x && x <= r[i])
			pos[i] = x;
		else if(x < l[i])
			pos[i] = l[i];
		else
			pos[i] = r[i];
	}
	sort(pos + 1, pos + 1 + n);
	for (int i = 1; i < n; i++) 
		ans += (pos[i + 1] - pos[i]) * i * (n - i);
	cout << ans << "\n";
	return 0;
}

T2

考虑枚举 \(b\) 中 \(1\) 的个数 \(x\),设第 \(i\) 行 \(1\) 的个数为 \(r\)。

  • \(r>x\) 时,选 \(0\) 那么 \(1\) 不够,必须选 \(1\)。
  • \(r<x\),同理必须选 \(0\)。
  • \(r=x\),选 \(0/1\) 随意。

对于方案数的统计,考虑设 \(a_x\) 表示 \(r\le x\) 行中 \(1\) 的并,\(b_i\) 表示 \(r>x\) 行中 \(0\) 的并。那么 \(a,b\) 不能有交集。当 \(r=x\) 时方案数显然是 \(2^{tot}\),\(tot\) 表示 \(r=x\) 的 \(i\) 的个数,对于 \(r\neq x\),\(n-a_x-b_x\) 的位置是确定的,\(x-pre_x\) 个 \(1\) 尚未确定,于是乘上 \({{n-a_x-b_x}\choose {x-a_x}}\)。

代码:

#include <bits/stdc++.h>
#define int long long
#define mod 998244353
#define N 5005
using namespace std;
int n;
int fac[N], inv[N];
int qpow(int x, int y) {
	int ans = 1;
	while (y) {
		if (y & 1)
			ans = ans * x % mod;
		x = x * x % mod;
		y >>= 1;
	}
	return ans;
}
int C(int n, int m) {
	if (n < m || n < 0)
		return 0;
	return fac[n] * inv[m] % mod * inv[n - m] % mod;
}
vector<int>ct[N];
bitset<N>a[N], b[N], c[N];
int ans;
signed main() {
	freopen("de.in", "r", stdin);
	freopen("de.out", "w", stdout);
	fac[0] = inv[0] = 1;
	for (int i = 1; i < N; i++)
		fac[i] = fac[i - 1] * i % mod;
	for (int i = 1; i < N; i++)
		inv[i] = qpow(fac[i], mod - 2);
	cin >> n;
	for (int i = 1; i <= n; i++) {
		int p = 0;
		for (int j = 1, x; j <= n; j++) {
			scanf("%1lld", &x);
			if (x) 
				c[i].set(j, 1);
			p += x;
		}
		ct[p].push_back(i);
	}
	for (int i = 1; i <= n; i++) {
		a[i] = a[i - 1];
		for (auto j : ct[i])
			a[i] |= c[j];
	}
	for (int i = 1; i <= n; i++) 
		b[n + 1].set(i, 1);
	for (int i = n; i >= 1; i--) {
		b[i] = b[i + 1];
		for (auto j : ct[i])
			b[i] &= c[j];
	}
	for (int i = 0; i <= n; i++)
		if ((a[i] & b[i]) == a[i]) {
			int c1 = a[i].count(), c2 = b[i].count();
			ans = (ans + qpow(2, ct[i].size()) * C(c2 - c1, i - c1) % mod) % mod;
		}
		cout << ans << "\n";
	return 0;
}

T3

首先显然考虑容斥。

设 \(g(i)\) 表示前 \(i\) 堆所有方案数,\(f(i)\) 表示其异或和为 \(0\) 的方案数。显然 \(g(i)=g(i-1)\times (2^n-i)\)。

对于 \(f(i)\),也就是前 \(i-1\) 个数的异或和和第 \(i\) 个数相等,初步的想法是 \(f(i)=g(i-1)-f(i-1)\)。但是考虑当前数列中的最后一个数可能在前 \(i-1\) 个数中出现。这个数值显然出自于 \([1,i-2]\),于是有 \(2^n-1-(i-2)=2^n-i+1\) 种值,除了这个数的排列有 \(f(i-2)\) 种,将这个数插入 \(i-2\) 个数中有 \(i-1\) 种情况,于是 \(f(i)=g(i-1)-f(i-1)-(2^n-i+1)\times(i-1)\times f(i-2)\)。

答案是 \(g(n)-f(n)\),时间复杂度为 \(O(n)\)。

代码:

#include <bits/stdc++.h>
#define N 10000007
#define int long long
#define mod 1000000007
using namespace std;
int n;
int qpow(int x, int y) {
	int ans = 1;
	while (y) {
		if (y & 1)
			ans = ans * x % mod;
		x = x * x % mod;
		y >>= 1;
	}
	return ans;
}
int f[N], g[N];

signed main() {
	freopen("yui.in", "r", stdin);
	freopen("yui.out", "w", stdout);
	cin >> n;
	int n2 = qpow(2, n);
	g[0] = 1;
	for (int i = 1; i <= n; i++)
		g[i] = g[i - 1] * ((n2 - i + mod) % mod) % mod;
	f[0] = 1;
	f[1] = 0;
	for (int i = 2; i <= n; i++)
		f[i] = (g[i - 1] - f[i - 1] - ((n2 - i + 1 + mod) % mod) * (i - 1) % mod * f[i - 2] % mod + mod + mod) % mod;
	cout << (g[n] - f[n] + mod) % mod << "\n";
	return 0;
}

T4

口胡出考虑最优的情况一定是一个团,然后跑 BK 即可。

代码就不放了。

标签:int,37,long,ans,fac,define,CSP,模拟,mod
From: https://www.cnblogs.com/Rock-N-Roll/p/18459384

相关文章

  • 多校A层冲刺NOIP2024模拟赛05
    A.好数(number)很容易想到\(n^3\)枚举两个,看第三个是否出现,扩展一下,枚举一个,看剩下需要的和是否出现过,提前处理出两两的和和最早能合出这个数的位置,复杂的\(O(n^2)\)点击查看代码#include<bits/stdc++.h>constintmaxn=5000+10;usingnamespacestd;intn,a[maxn],cnt,......
  • CSP-J 2023 T3 一元二次方程 解题报告
    CSP-J2023T3一元二次方程解题报告Link前言今年\(CSP\)的原题,回家\(1h\)内写\(AC\),但是考场上没有写出来,原因是脑子太不好了,竟然调了两个小时没有调出来.一等奖悬那......正题看完题目,第一眼就是大模拟,并且\(CCF\)绝对不会让你好受,所以出了一个如此***钻的......
  • CSP-S 模拟赛 36
    CSP-S模拟赛36T1由于\(a_i\le10^5\),那么考虑枚举这个\(\gcd\),考虑求\(f(i)\)表示答案,那么\(\operatorname{ans}=\sumi\timesf(i)\)。然而式子中有\(\gcd\),于是考虑求\(g(i)\)表示\(i\mid\gcd\)的方案数,然后\(f(i)=g(i)-\sum_{j>i,i\midj}f(j)\)。对于\(g(i)\)......
  • 代码随想录Day23 | LeetCode 455. 分发饼干、LeetCode 53. 最大子数组和、LeetCode 37
    LeetCode455.分发饼干贪心就是干classSolution:deffindContentChildren(self,g:List[int],s:List[int])->int:g.sort(reverse=True)s.sort(reverse=True)i=j=0res=0whilei<len(g)andj<len(......
  • CSP-S 模拟赛35
    CSP-S模拟赛35T1其实是傻逼题。常见的套路是枚举右端点,动态维护左端点的贡献。发现右端点移动一位只会对一种颜色有影响,那么考虑线段树维护区间的答案,区间加减每个颜色即时的贡献即可。代码:#include<bits/stdc++.h>#defineN1000005#defineM8005#defineintlonglong......
  • 代码随想录算法训练营 | 完全背包,518. 零钱兑换 II,377. 组合总和 Ⅳ,70. 爬楼梯 (进阶)
    完全背包题目链接:完全背包文档讲解︰代码随想录(programmercarl.com)视频讲解︰完全背包日期:2024-10-11想法:dp数组设置思路跟01背包一样,不同在遍历上,完全背包遍历背包大小是从weight[i]开始的(背包空间小于weight[i]就没有意义,不用考虑,直接用之前的对应数值就行了),从前往后遍历就能......
  • 『模拟赛』多校A层冲刺NOIP2024模拟赛05
    Rank烂。A.好数(number)签,唐,没签上。考虑之前几次类似的题方法都是选\(k-1\)的方案存起来以使总复杂度除以一个\(n\),故考虑记共\(n^2\)个两两组合之和,枚举当前点\(i\)前面的点,找是否有值为它们的差的组合,复杂度\(\mathcal{O(n^2)}\),用map记再挂个\(\logn\)。赛......
  • 多校A层冲刺NOIP2024模拟赛05
    T1、好数(number)签到题把选三个数相加拆为选择一个数,然后看前面有没有能用两个数组合出答案。$O(n^2)$。码(#include<bits/stdc++.h>usingnamespacestd;typedeflonglongll;typedefunsignedlonglongull;typedefpair<int,int>pii;#definemkmake_pair#de......
  • [10.11]CSP-S模拟赛
    宝贵经验:写题的时候想出时间正确的方法后千万注意计算空间,能不用数组的地方就不要用,否则可能会像我一样:\(35\to15\to0\)赛前小L说比上次简单。赛时T1一开始没有思路,但是注意到了两个关键条件:询问数\(\le300\)\(n,m\le10^9\)然后想到正解绝对不是去直接修改。注......
  • c语言模拟实现库函数 strlen strcpy strcat strcmp strstr
    一、模拟实现库函数strlen解释:strlen是求字符串长度的,求出的长度是不可能为负数所以返回类型设置为size_t也是合情合理的 typedefunsignedintsize_t\注意字符串已经'\0'作为结束标志,strlen函数返回的是在字符串中'\0'前面出现的字符个数(不包含'\0')。size_......