首页 > 其他分享 >ABC 261 复盘

ABC 261 复盘

时间:2024-05-12 17:53:01浏览次数:24  
标签:ABC int namespace long 261 l2 using 复盘 逆序

ABC 261 复盘

[ABC261A] Intersection

思路解析

因为这题czl错了所以我特地来写个复盘

可以想到两条线段的关系只有不相交,相交,包围三种,于是我们可以直接判断每种情况然后输出就好了,可以在判断前先将两条线段的位置判断一下交换方便之后操作。

#include<bits/stdc++.h>
using namespace std;
int l1, r1, l2, r2;
signed main() {
	cin >> l1 >> r1 >> l2 >> r2;
	if(l1 > l2) swap(l1, l2), swap(r1, r2);
	if(r1 >= r2) cout << r2 - l2;
	else if(r1 >= l2) cout << r1 - l2;
	else cout << 0;
	return 0;
}

[ABC261D] Flipping and Bonus

思路解析

是一个简单 dp。用 \(f_{i,j}\) 表示现在是第 \(i\) 轮抛硬币,计数器上的数是 \(j\),同时设 \(t_{C_i}=Y_i\)。分为两种情况转移;若当前硬币为正面,则 \(f_{i,j} \gets f_{i-1,j-1}+X_i+t_j\);若当前硬币为反面,则 \(f_{i,0} \gets f_{i-1,j}\)。

最后注意判断转移时传过来的元素是否有值。

code

#include<bits/stdc++.h>
#define int long long
#define PII pair<long long, long long>
#define fir first
#define sec second
using namespace std;
const int N = 5010;
int n, m, c[N], f[N][N];
PII s[N];
map<int, int> mp;
signed main() {
	memset(f, -1, sizeof(f));
	cin >> n >> m;
	for(int i = 1; i <= n; i++) cin >> c[i];
	for(int i = 1; i <= m; i++) {
		cin >> s[i].fir >> s[i].sec;
		mp[s[i].fir] = s[i].sec;
	}
	f[0][0] = 0;
	for(int i = 1; i <= n; i++) {
		for(int j = 0; j <= n; j++){
			if(f[i - 1][j] >= 0) f[i][0] = max(f[i][0], f[i - 1][j]);
			if(j > 0 && f[i - 1][j - 1] >= 0) f[i][j] = max(f[i][j], f[i - 1][j - 1] + c[i] + mp[j]);
		}
	}
	int ans = 0;
	for(int i = 0; i <= n; i++) ans = max(ans, f[n][i]);
	cout << ans;
	return 0;
}

[ABC261E] Many Operations

思路解析

首先可以发现,如果直接跑肯定会炸,于是考虑优化。首先发现操作有很多重复的,所以可以考虑把每一个数经过所有操作后的值都预处理下来,但这样显然空间也会炸。然后我们又想到可以不需要求下每个数经过操作后的值,可以把每一位二进制上在开始前是 \(0\) 还是 \(1\) 的情况记录下来,然后在需要查询时遍历每一位,把每一位上对应二进制的值取出来再相加即可。

还有就是尽量不要用我的代码的实现去写,看上去十分丑陋不便于调试,可以直接用 bitset 或整形变量存储,没必要使用 dp。

code

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N = 2e5 + 10;
int n, c;
int f[2][N][32];
signed main() {
	cin >> n >> c;
	for(int i = 0; i <= 30; i++) f[1][0][i] = 1;
	for(int i = 1, op, x; i <= n; i++) {
		cin >> op >> x;
		for(int j = 0; j <= 30; j++) {
			int t = ((x >> j) & 1);
			for(int k = 0; k < 2; k++) {
				if(op == 1) f[k][i][j] = f[k][i - 1][j] & t;
				else if(op == 2) f[k][i][j] = f[k][i - 1][j] | t;
				else if(op == 3) f[k][i][j] = f[k][i - 1][j] ^ t;
			}
		}
		int res = 0;
		for(int j = 0; j <= 30; j++) {
			int t = ((c >> j) & 1);
			res += (f[t][i][j] << j);
		} c = res;
		cout << res << '\n';
	}
	return 0;
}

[ABC261F] Sorting Color Balls

思路解析

首先我们可以考虑如果没有 \(C\) 的情况下那答案就是 \(X\) 中逆序对的个数。接下来想如果加入了 \(C\),那答案减去的部分的每个逆序对 \((i,j)\),都有 \(C_i=C_j\);也就是说,只有对于 \(C_i=C_j\) 的数对 \((i,j)\) 才有可能对答案造成贡献;而同时,只有 \(X_i>X_j\) 才会对答案造成贡献,所以我们只需要对于每一个 \(C_{d_1}=C_{d_2}=C_{d_3}\dots\) 求序列 \(W_{d_1},W_{d_2},W_{d_3}\dots\) 的逆序对数即可。

求逆序对的方法很多,这里我用的是树状数组法,记得要在每次求完逆序对后撤销原来的操作。

code

#include<bits/stdc++.h>
using namespace std;
const int N = 5e5 + 10;
namespace BIT {
	const int B_SIZE = 5e5 + 10;
	int B[B_SIZE + 10];
	void add(int x, int y) {
		for(; x <= B_SIZE; x += (x & -x)) B[x] += y;
	}
	int ask(int x) {
		int sum = 0;
		for(; x > 0; x -= (x & -x)) sum += B[x];
		return sum;
	}
}
using namespace BIT;
int n, c[N], d[N];
vector<int> v[N];
long long nxd(int x) {
	long long res = 0;
	for(auto it : v[x]) {
		res += ask(n + 1) - ask(it);
		add(it, 1);
	} 
	for(auto it : v[x]) add(it, -1);
	return res;
}
signed main() {
	cin >> n;
	for(int i = 1; i <= n; i++) cin >> c[i];
	for(int i = 1; i <= n; i++) cin >> d[i];
	long long ans = 0;
	for(int i = 1; i <= n; i++) {
		ans += ask(n + 1) - ask(d[i]);
		add(d[i], 1);
	}
	for(int i = 1; i <= n; i++) add(d[i], -1);
	for(int i = 1; i <= n; i++) v[c[i]].push_back(d[i]);
	for(int i = 1; i <= n; i++) ans -= nxd(i);
	cout << ans;
	return 0;
}

标签:ABC,int,namespace,long,261,l2,using,复盘,逆序
From: https://www.cnblogs.com/2020luke/p/18187999

相关文章

  • ABC353 | 如同流星划过天空
    ABC353|如同流星划过天空A.&B.依题意模拟即可。C.注意只有\(f(x,y)\)需要对\(10^8\)取模,\(f\)的求和不需要。关注到\(a_i\in[1,10^8)\),故\(a_i+a_j\in[2,2\times10^8)\)。从而\(f(x,y)=[x+y<10^8](x+y)+[x+y\ge10^8](x+y-10^8)=x+y-10^8[x+y\ge10^......
  • ABC353C Sigma Problem 题解
    ABC353CSigmaProblem题解题目链接:AT题目中的两个求和符号\(\sum_{i=1}^{N-1}\sum_{j=i+1}^{N}\)实际上是在枚举所有的有序数对\((i,j)\)。而有序数对的个数\(N(N-1)/2=O(N^{2})\),真的去枚举所有数对肯定会T。这时应该考虑去拆贡献,求出每个\(A_i\)对答案的贡献。......
  • ABC353E字典树处理最长公共前缀
    https://atcoder.jp/contests/abc353/tasks/abc353_e其实就是字典树板子题。似乎遇到最长公共前缀,就该想到字典树。依次加入每个字符串:维护一个数组siz来统计在当前串之前的串在对应点的出现次数。手模一下字典树的建树过程,显然如果当前串\(S_i\)能跑到一个曾经串\(S_......
  • ABC353
    不知道为啥有断更了一周...Ewoc,怎么跟我出的题目这么像先把字符串扔到一个Trie里面,然后对于每一个点我们考虑这一个点到根节点组成的字符串能是多少对字符串的最长公共前缀。我们定义\(cnt_u\)表示共有多少个字符串的结尾在以\(u\)为根的子树内。对于\(u\)节点,其贡献......
  • 【做题纪要】ABC351
    【做题纪要】ABC351昨天ABC打了三道题就去看别人颓了,也是喜提\(\text{-20rated}\)不懂,就我这棕色的名字还能扣\(\text{rated}\)吗?早知道认真打了特别感谢:文心一言对于题目的翻译支持A-Thebottomoftheninth题意高桥队和青木队正在进行一场棒球比赛,高桥队首先进行......
  • abc146e-ti-jie
    abc146e思路由题,$k\mid(a_l+a_{l+1}+...+a_{r-1}+a_r)-(r-l+1)$,可以转换为平均每个数在模$k$下都贡献了$1$。所以对区间每个数都减$1$,则长度为$len$的区间和减了$len$,此时如果区间和为$k$的倍数则符合条件。预处理对$k$取模的前缀和$sum_i$,如果$sum_{l-1}=sum_r$......
  • abc349g-ti-jie
    abc349g思路从前往后枚举$i$,每次对$i+1\lej\lei+a_i$的$j$赋值$b_j=b_{i\times2-j}$。同时有$b_{i+a_i+1}\neb_{i-a_i-1}$。用$ban_{i,j}$记录$i$不能是$j$,如果要给$i$赋值就选最小的。最直接的就是并查集倍增将两段区间并起来。可以用类似马拉车的思路得......
  • ATcoder ABC 352 F - Estimate Order 搜索
    很恶心的一个搜索,当然好像不用搜索也能做。没啥好讲的,一个联通块大小>=2就要搜索找位置,联通块大小等于1的不用搜。能调出来也是真不容易。#include<bits/stdc++.h>#defineintlonglong#defineDBdoubleusingnamespacestd;intn,m,tsiz,yinum;constintN=23;intfa[......
  • 「杂题乱刷」AT_abc096_d
    对下脑电波。题目链接(luogu)题目链接(at)发现我们可以找出所有\(x\)当且仅当\(x\)为质数且\(x\bmod5=3\),这样任意五个数加起来就必定为合数了。代码:点击查看代码/*Tips:你数组开小了吗?你MLE了吗?你觉得是贪心,是不是该想想dp?一个小时没调出来,是不是该考虑换题......
  • ABC240Ex Sequence of Substrings
    ABC240ExSequenceofSubstringsLIS的好题改编。约定\(S(l,r)\)为字符串\(s\)中第\(l\)位到底\(r\)​位。\(S(l,r)<S(x,y)\)为字符串中\([l,r]\)的子串字典序比\([x,y]\)的子串小。前置LIS的\(n\logn\)求法。题解我们考虑按照类似于朴素LIS的方式设状......