csp 之前做题记录

2022.10.24

子只因只因数

题意:你养了很多二进制鸡,对于每个 \(i\),求序列的合法子鸡个数。

赛时只计算了预处理所有品种的鸡的子鸡只有 \(2e7\) 级别,然而忘了查询的时候重复的鸡是不可避免的……不过学到了 STL,不亏不亏。

考虑分块,就很神奇,其实做的时候想过前缀和,但是发现二进制没法前缀和,忘了优化方法还有树状数组和分块。

不过总算是知道了该怎么分块(大概是分成黄金鸡块),总之收获非常大吧!感谢 Acestar 的帮助!

我想给网易云充个会员,有人 v 我 50 吗。

#include <bits/stdc++.h>
using namespace std;
int main(){
	cin >> n;
	for(int i = 1; i <= n; ++i) cin >> chicken[i]; //读入
	node goldchickenkuai = sqrt(chicken[0]); //分块 
	do{
		sing();
		jump();
		rap();
		basketball();
	}while(goldchichenkuai.beautiful = true); //预处理 
	for(int i = 1; i <= n; ++i) cout << goldchickenkuai.erjinzhi << '\n'; //输出二进制
	return 0;
}

2022.10.25

布尔表达式

题意:有一个表达式,但是它自己把括号丢了,请你输出 YesNo

我严重怀疑这题没做出来是因为我太摆了,刚想想上一道 bool 题的做法就想:“唉这道题是大模拟太难了我还是先看 T4 吧” 或者 “唉这个做法太难了我还是先想想怎么直接让一段做贡献吧”。然后最大子矩阵也是这么摆的,刚想推式子就想:“推式子太麻烦了我还是先不推了”。不过今天的借口是我太困了必须要与模拟赛作斗争,罚坐 2h 的滋味不是很妙但也挺妙的,希望考 csp 的时候能顺理成章地推下去,也衷心希望 csp 那天上午能够睡觉

还有一个原因是我发现这么好的性质后想:“这么好的性质!我可不能按照平常的做法来,我要顺着性质想下去!” 然后我就把上一个题扔了,然后要是出题人也这么想的话,事实是 Ignotus 用这么好的做法吊打了 std,傻眼。

考虑使用 Ignotus 的做法,然后就没了。

#include <bits/stdc++.h>
using namespace std;
bool success; //存储布尔表达式的值 
void HE(string name){
	if(name.rangnihe) success = 1; //贺 Ignotus 的代码 
	return;
}
int main(){
	string s;
	cin >> s; //输入表达式
	HE("Ignotus");
	if(success) puts("Yes"); //输出答案 
	else puts("No"); 
	return 0;
}

2022.10.26

覆盖

题意:如果一个大串能覆盖一个小串,则称大串 “覆盖” 了小串,给你一个麻辣串,问你合法串的个数。

要是不做这个题我都忘记有树这个东西了……

具体而言就是把所有串都放在树状数组上查询,注意,合法的甜不辣是没有鱼腥味的。大串不太好做,所以我们只考虑小串,发现合法的小串在树状数组上是连续的!然后其实在树上直接树状数组就可以(这玩意还是看代码才懂的),然后最后加点麻酱清汤和香菜就好了,感觉还是很麻烦的。

神 youwike 的做法就很神奇,直接用 z 函数,反正是只计算一个位置然后貌似点是只增不减的,然后就可以直接维护!代码比上面要短,但从来没想过还能用到这个神奇的性质,不过想到了还需要想到数据结构去维护,我觉得我肯定想不到,还是在树上涮吧……(不过也未必?好像不同的方向会有不同的性质。)

#include <bits/stdc++.h>
using namespace std;
struct skewer{
	int o[5]; 
}s;
int lowbit(int oooo){ //四个丸子 
	int stick = -oooo; //用签子穿起来 
	return oooo & stick;
}
//树状数组 
void add(int x){
	while(x <= n) x += lowbit(x);
	return;
}
int query(int x){
	while(x) x -= lowbit(x);
	return x;
}
int main(){
	for(int i = 1; i <= 4; ++i) cin >> s.o[i]; //输入一个串 
	add(s.o[0]); //建树
	for(int i = 1; i <= 4; ++i)
		if(ask(s.o[i]) == fish){ //特判海鲜 
			puts("-1");
			return 0;
		}
	for(int i = 1; i <= 4; ++i)
		cout << ask(s.o[i]); //对于每一个前缀输出答案 
	return 0;
}

完结了,一是 csp2022 结束了,二是好像没人看。

posted @ 2022-10-06 16:08  Fideow  阅读(114)  评论(4)    收藏  举报