首页 > 其他分享 >CF-1920-div2 总结

CF-1920-div2 总结

时间:2024-01-14 14:13:04浏览次数:44  
标签:return int CF long 1920 num que len div2

1.结果

赛时做出:AB(D)

赛后做出:CD

评分变化:1535->1500

rank:4521

2.赛后总结

>1 个人评价

这次比赛是我寒假的第一次,昨天坐了一天的动车,虽然平稳,但还是有晕车,导致晚上状态不好,个人因素还是有的。最主要的因素还是后一个小时太晕了,D题有个小问题没发现。
除此之外,近期开始服用的药物让我很晕,这种药还是得继续吃下去,后续还得继续适应这样的情况。
这次的结果并不满足,还得继续。

2> 题目评价

总的来说,这次的题目CD难度不是很大。
C题比赛过程中完全没有思路,一开始想到了gcd,接下来就想到分块处理,不过对于不同因数的分块不能动态做,因此思路终结。同时,对于如何找到m也没有任何思路,于是考试直接放弃。
D题的思路很清楚,而且第一遍写出代码后就通过了样例,不过在后续过程的思考中,对后续过程取模的改动没有让吴想到改进之前取模的过程,因此喜提+2。补题时发现题解思路和我的一模一样,头都大了
补题的时候看了下E,不是很理解,所以停止补题。

3.题目解答

题意是求满足条件的个数,有123三种要求,思路是存3,求1的最大值,2的最小值,然后先让ans=Min2 - Max1 + 1,接着判断3中有几个数在范围之内,ans减去这个数字,得出结果。

通过的代码
#include <iostream>
using namespace std;

int main() {
	int t;
	cin >> t;
	while (t--) {
		int ma = 0, mi = 1e9;
		int n;
		int a[101], cnt = 0;
		cin >> n;
		for (int i = 1; i <= n; i++) {
			int x, y;
			cin >> x >> y;
			if (x == 1)
				ma = max(ma, y);
			if (x == 2)
				mi = min(mi, y);
			if (x == 3)
				a[++cnt] = y;
		}
		int ans = mi - ma + 1;
		for (int i = 1; i <= cnt; i++)
			if (a[i] >= ma && a[i] <= mi)
				ans--;
		if (ans > 0)
			cout << ans << endl;
		else
			cout << 0 << endl;
	}

	return 0;
}

这道题就是求博弈之后的最小值。
先把所有数从大到小排序。
bod的操作及其简单,就是把删除后序列的最大值全部取反
Alice的操作就有点麻烦了,我们就思考删除一个数之后会怎么样。首先,要总和最大,删除的肯定是bob会取反的数。假设删除一个数,bob就会把取反区间的后一个数取反,对结果而言,ans-2*bob选的数+alice删除的数。对Alice而言,删除第一个数是最优解。
所以,我们发现,这个就像滑动区间,假设Bob选取的区间为S,则结果ANS = S后面的总和 - S的总和。加入前缀和优化计算。

点击查看代码
#include <iostream>
#include <algorithm>
using namespace std;

bool cmp(const int a, const int b) {
	return a > b;
}

void charge() {
	int n, x, k;
	cin >> n >> k >> x;
	int a[200010] = {0};
	long long sum[200010] = {0};
	for (int i = 1; i <= n; i++)
		cin >> a[i];
	sort(a + 1, a + 1 + n, cmp);
	for (int i = 1; i <= n; i++)
		sum[i] = sum[i - 1] + a[i];
	long long ans = -1e18;
	for (int i = 0; i <= k; i++) {
		if (i + x < n)
			ans = max(ans, sum[i] - sum[i + x] * 2 + sum[n]);
		else
			ans = max(ans, sum[i] - sum[n]);
	}
	cout << ans << endl;
}

int main() {
	int t;
	cin >> t;
	while (t--) {
		charge();
	}

	return 0;
}

这个是求不相交子区间是否存在一个模m使得所有子区间取模后的序列一样。
首先,分出子问题:已知A,B,求m,存在 A ≡ B (mod m)。对于这个问题,直接把等式一边移到另一边。可以得出m是|A-B|的因数。
扩大问题,序列相等就说明每一位与其对应的下一段子区间的数取m后相等。因此,想到GCD,求取每一位对应位置的GCD,如果结果相同,ans++。
最后,求n的所有因数。
*注:并不是所有看似ON2的结果都是ON2,思考过程中是否存在舍弃的部分。

点击查看代码
#include <iostream>

using namespace std;

long long gcd(long long x, long long y) {
	if (x < y)
		return gcd(y, x);
	if (y == 0)
		return x;
	return gcd(y, x % y);
}

void charge() {
	int n, a[200010];
	cin >> n;
	for (int i = 1; i <= n; i++)
		cin >> a[i];
	int ans = 0;
	for (int i = 1; i <= n; i++) {
		if (n % i == 0) {
			int g = 0;
			for (int j = 1; j + i <= n; j++) {
				g = gcd(g, abs(a[j + i] - a[j]));
			}
			if (g != 1)
				ans++;
		}
	}
	cout << ans << endl;
}

int main() {
	int t;
	cin >> t;
	while (t--) {
		charge();
	}

	return 0;
}

D Array Repetition >http://codeforces.com/contest/1920/problem/D< (补)

给出使用两种方式生成的数组,求第k位的字符。
首先,假设长度为len的数组,求第k位。如果最后一个操作是尾部增加同时k=len,那该问的结果就是末尾增加的字符,若不等,则len--。如果是第二种操作,求取k在未加倍前的位置即可。
该过程可以使用经过堆优化的离线做法,优化结果。
就是这个取模,害的我+2

点击查看代码
#include <iostream>
#include <queue>

#define MAX 1e18

using namespace std;

struct node {
	long long num;
	int iter;
	bool operator>(const node a) const {
		return num < a.num;
	}
	bool operator<(const node a) const {
		return num > a.num;
	}
};

priority_queue<node, vector<node>, greater<node>> que;

int x[200010];
int y[200010];

void charge() {
	int n, q;
	cin >> n >> q;
	for (int i = 1; i <= n; i++)
		cin >> x[i] >> y[i];
	long long k, MAXk = 0;
	for (int i = 1; i <= q; i++) {
		cin >> k;
		MAXk = max(MAXk, k);
		node p;
		p.iter = i;
		p.num = k;
		que.push(p);
	}
	long long len = 0, cnt = n;
	for (int i = 1; i <= n; i++) {
		if (x[i] == 1) {
			if (len == MAXk) {
				cnt = i - 1;
				break;
			}
			len++;
		} else {
			if (MAXk / len < y[i] + 1) {
				cnt = i - 1;
				break;
			}
			len *= y[i] + 1;
		}
	}
	while (que.top().num > len) {
		node p = que.top();
		que.pop();
		p.num = (p.num - 1) % len + 1;
		que.push(p);
	}
	int ans[200010];
	for (int i = cnt; i >= 1; i--) {
		if (x[i] == 1) {
			while (!que.empty()) {
				if (que.top().num < len)
					break;
				node p = que.top();
				que.pop();
				ans[p.iter] = y[i];
			}
			if(que.empty())
				break;
			len--;
		} else {
			len /= y[i] + 1;
			while (que.top().num > len) {
				node p = que.top();
				que.pop();
				p.num = (p.num - 1) % len + 1;
				que.push(p);
			}
		}
	}
	for (int i = 1; i <= q; i++)
		cout << ans[i] << " ";
	cout << endl;
}

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

标签:return,int,CF,long,1920,num,que,len,div2
From: https://www.cnblogs.com/slotifnotias/p/17963665

相关文章

  • 浅谈Linux下傻瓜式磁盘分区工具cfdisk的使用
    对于新手来说,Linux环境下的磁盘分区可能还会存在一些困难。对于熟悉Linux的朋友来说,我们还有fdisk、parted(2TB以上的磁盘分区使用)等磁盘分区工具可以使用。在我们新增磁盘或者在原来磁盘上进行扩容时就会使用到磁盘分区工具,磁盘分区对于整个系统的管理十分重要。1.增加一块容量......
  • 【树上启发式合并】CF1709E XOR Tree
    XORTree\(\mathtt{TAGS}\):树上启发式合并+异或+贪心\(\mathtt{ESTIMATION}\):非常好的启发式合并题目First.如何去除\(0\)路径对于一条路径\(u\tov\),要使其不为\(0\)肯定是将\(\mathtt{LCA}(u,v)\)变为\(2^{30+x}\)最好,这样异或值的第\(30+x\)位一......
  • 矩阵乘法 - CF678D Iterated Linear Function
    CF678DIteratedLinearFunction题意\(f_{i,x}=A\timesf_{i-1,x}+B\)且\(f_{0,x}=x\)求\(f_{n,x}\)。思路这道题的递推关系十分清晰。但由于数据范围大(\(1\leA,B,x\le10^9,1\len\le10^{18}\)),所以这道题只能使用矩阵乘法加速递推。矩阵的构造我们需要构造一个......
  • 模拟 - CF1196C Robot Breakout
    RobotBreakout(CF1196C)思路这道题因为平面极大,暴力枚举每个点肯定会超时。所以,我们不妨从机器人出发。我们可以枚举每个机器人可以执行的操作:位置从\((X_i,Y_i)\)变为\((X_i-1,Y_i)\),即向左走。位置从\((X_i,Y_i)\)变为\((X_i,Y_i+1)\),即向上走。位置从\((X_......
  • CF1016D Vasya And The Matrix Solution
    题目传送门做法因为是异或运算,可以按位考虑。先预处理出行(\(a[i]\))异或和\(suma\),与列(\(b[i]\))的异或和\(sumb\)。如果\(suma\nesumb\),那就说明无解,因为\(suma\)和\(sumb\)最后都代表着整个矩阵的异或和,如果两者不相等,那就说明矛盾,无解。否则就一定......
  • CF414B - Mashmokh and ACM
    思路dp。dp[i][j]表示第i位填j时的方案数ac代码#include<bits/stdc++.h>usingnamespacestd;usingi64=longlong;consti64inf=8e18;typedefpair<int,int>pii;constintmod=1e9+7;constintN=2e3+5;intdp[N][N];vector<int>g[N];voi......
  • CF-613-D
    613-D题目大意给定一颗\(n\)个节点的树。\(q\)组询问,每组询问给定\(k\)个点,问至少要删除树中多少个点才能使这\(k\)个点两两不连通,无解则输出\(-1\)。这里\(\sum{k_i}\)的规模大致和\(n\)相当。Solution虚树模板题。暴力的做法是每组询问都对整棵树进行遍树形DP,复杂度为\(......
  • CF1201C - Maximum Median
    思路二分答案。对于一个mid,查询中位数要是为mid的话至少要做多少次操作,最小操作次数就是排序后从中位数开始计算max(0,mid-v[i])的和ac代码#include<bits/stdc++.h>usingnamespacestd;usingi64=longlong;consti64inf=8e18;typedefpair<int,int>pii;cons......
  • CF1876D Lexichromatography
    CF1876DLexichromatographyLuoguCF1876D题目描述给定一个长为\(n\)的序列\(a\),你需要对这个序列进行红蓝染色。染色有如下要求:每个位置恰好染上其中一种颜色。对于所有的值\(k\),在这个序列的任意子区间\([l,r]\)中,值为\(k\)且为红色的位置数减去值为\(k\)且为......
  • CF713D 题解
    题意给一个\(01\)矩阵,多次求在给定区间内最大的全\(1\)正方形边长。思路容易想到二分:先预处理出以每个位置为右下角的最大合法正方形的边长\(mx_{i,j}\),然后对于每个询问,我们二分边长\(mid\),设当前询问的区间左上角为\((x_1,y_1)\),右下角为\((x_2,y_2)\),则能取到\(mi......