2021.11.13 dmy模拟赛2

前言

(mathtt{No Excuse}) 菜是原罪
穷则变,变则通,通则久。

得分:(10+30+60+10=110pts)
这场考试有点坐牢了啊...Q^Q
暴力的分谁都会,不暴力的我又像不太出来。
原本预期是要在模拟赛运用对拍,结果根本没有高分程序,拍个寂寞(根本没分可挂)。

时间大部分运用在 (T3),一开始想是区间 DP,后来发现答案一段一段的性质就写了个 (O(n^3)) DP,结果死活调不过去。又写了个暴搜,也调不过去。本场考试这里应该是比较失败的吧。。。可能 DP 本来也超出我的水平范围,写不出来也正常。。但是暴搜挂的就有点难以理解了。

(T1,T2) 又是死脑筋了,暴力倒是写的飞快,可惜没啥用。
(T1) 开场就看到有个特殊性质引导想正解,很快推出特殊性质,结果正解靠不过来。赛后一讨论才发现,把一整块看成一个元素,那么所有元素就组成了特殊性质,而每个元素内部不是顺序就是逆序,只需在原本的特殊情况上加一点判断即可。虽然说与正解失之交臂很遗憾,但是确实是脑子没转过来。((T1) 还可平衡树做,但是我不会,而且这种线性做法更值得学习)

(T2) 体现出做题思路及技巧的不灵活,这个数据范围自然想到矩阵乘法优化线性 DP,然而线性 DP 看题目根本想不出来,于是只能放弃。实际上,跑过 (5000) 的数据之后完全可以发现数据稀疏,打表过 (60)(这完全没有难度),对于满分,需要进一步地观察打表数据,有完全平方数和递推式。数学题达标看规律也是一种做题的方法啊!

(T4) 看出来了是个容斥,但是感觉比较复杂,难以做对,于是放弃。

考砸了也没关系,明天还有模拟,还可以测试对拍的时间策略,还可以试着学习灵活的做题思路。加油!

题解

A reverse

从后往前扫一遍,维护一个一次函数记录位置为 (x) 的点最后到了哪里。复杂度为 (O(n))

reverse
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define FCC fclose(stdin),fclose(stdout)
const int INF = 0x3f3f3f3f,N = 5e5+10;
inline ll read()
{
	ll ret=0;char ch=' ',c=getchar();
	while(!(c>='0'&&c<='9')) ch=c,c=getchar();
	while(c>='0'&&c<='9') ret=(ret<<1)+(ret<<3)+c-'0',c=getchar();
	return ch=='-'?-ret:ret;
}
int n,k,a[N];
char s[N];
void viol()
{
	for(int i=1;i<=k;i++)
	{
		for(int j=1;j<=a[i]>>1;j++)	
			swap(s[j],s[a[i]-j+1]);
	}
	printf("%s
",s+1);
}
void sub()
{
	if(k&1)
	{
		for(int i=k;i>=1;i-=2) 
			for(int j=a[i];j>=a[i-1]+1;j--) putchar(s[j]);
		for(int i=2;i<=k-1;i+=2) 
			for(int j=a[i-1]+1;j<=a[i];j++) putchar(s[j]);	
	}
	else 
	{
		for(int i=k;i>=2;i-=2) 
			for(int j=a[i];j>=a[i-1]+1;j--) putchar(s[j]);
		for(int i=1;i<=k-1;i+=2) 
			for(int j=a[i-1]+1;j<=a[i];j++) putchar(s[j]);
	}
	for(int i=a[k]+1;i<=n;i++) putchar(s[i]);
	puts("");
}
int main()
{
	//freopen("reverse.in","r",stdin);
	//freopen("reverse.out","w",stdout);
	n=read(),k=read();
	scanf("%s",s+1);
	for(int i=1;i<=k;i++)
	{
		a[i]=read();
	}
	sub();
	FCC;
	return 0;
}
/*
6 5 
123456
1 2 3 4 5 
*/

B

利用Veta Jump 可以发现,如果 (x^2+y^2=k(xy+1)),其中 (x<y),则((x, kx-y)) 也是一组解并且字典序更小。因此初解一定形如 ((x, x^3)),然后倒推即可。

求出所有解后每次二分即可得到答案。

C

容易证明,一个方案合法当且仅当区间两两不包含,且如果最终 (a[j]) 出现在了位置 (i)(a[j])(j)(i) 范围里的最小值。利用DP计数即可。

D

考虑容斥哪些行、列要求没有树,枚举对角线是否要求没有树、枚举要求没有树的位置是否必须有树。可以背包出对角线被 ban 而行列均没被 ban 的格子数和选择的行列数,利用此计算出答案。复杂度为 (O(2^7 poly (n))).

原文地址:https://www.cnblogs.com/conprour/p/15548287.html