cometoj contest 6(记录型博客)

2 篇文章 0 订阅

前言
由于时间过少,这里仅仅记录我自己的思路(给自己看的),如果你有兴趣可以看看原题,再看看我写的,但是一般情况下不会很友好,此类文章在以后都会标记“(记录型博客)”

A

我们发现,所有的剩余量一定是
a + 2 b a+\sqrt 2 b a+2 b或者是 C − ( a + 2 b ) C-(a+\sqrt 2 b) C(a+2 b)的形式
把所有这些形式的全部抽出来
分析一下种类好像不是很多,然后建图跑最短路即可

B

首先有个性质,就是这么生成的树的直径一定是小于等于 O ( l o g n ) \mathcal O(logn) O(logn)
然后考虑dp
f u , l f_{u,l} fu,l表示以 u u u为根,直径不超过 d d d,距离 u u u的最远点距离不超过l的子树最多包含的点数
转移是对于每个 f u , l f_{u,l} fu,l,加入儿子,枚举儿子更新到的 l l l,我们发现只需要 l + s + 1 ≤ d l+s+1\le d l+s+1d即可,所以是一个前缀max形式,对于 s + 1 > l s+1>l s+1>l的情况另外处理一遍即可
然后,在枚举删去点的数量的时候,我们只需要枚举剩余直径长度即可,所以要扫 O ( l o g n ) \mathcal O(logn) O(logn)遍,每遍复杂度 O ( n l o g n ) \mathcal O(nlogn) O(nlogn)
综上总复杂度 O ( n l o g 2 n ) \mathcal O(nlog^2n) O(nlog2n)

C

排序后直接统计相邻两个数相差大于m的数量即可

D

感觉是构造题?
n n n是奇数的话
1 2 3 ⋅ ⋅ ⋅ n − 1 n n 1 2 ⋅ ⋅ ⋅ n − 2 n − 1 n − 1 n 1 ⋅ ⋅ ⋅ n − 3 n − 2 ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ 2 3 4 ⋅ ⋅ ⋅ n 1 \begin{matrix} 1&2&3&···&n-1&n\\ n&1&2&···&n-2&n-1\\ n-1&n&1&···&n-3&n-2\\ ···&···&···&···&···&···\\ 2&3&4&···&n&1 \end{matrix} 1nn1221n33214n1n2n3nnn1n21
就好了
然后若 n = 4 n=4 n=4
1 2 3 4 4 3 2 1 2 1 4 3 3 4 1 2 \begin{matrix} 1&2&3&4\\ 4&3&2&1\\ 2&1&4&3\\ 3&4&1&2\\ \end{matrix} 1423231432414132
之后就构造了
设已经求出答案为 n n n的矩阵 A ( n ) A(n) A(n)
沿着对角线翻转的矩阵为 A ′ ( n ) A'(n) A(n)
现在要对新的 n n n求答案,设 n = 2 k n=2k n=2k
A ( 2 k ) = { A ( k ) + k A ′ ( k ) A ( k ) % k + 1 A ( k ) + k } A(2k)=\left\{ \begin{matrix} A(k)+k&A'(k)\\ A(k)\%k+1&A(k)+k \end{matrix}\right\} A(2k)={A(k)+kA(k)%k+1A(k)A(k)+k}
由于 A ( k ) + k A(k)+k A(k)+k本身不会不满足对称的性质
考虑 A ( k ) % k + 1 A(k)\%k+1 A(k)%k+1 A ′ ( k ) A'(k) A(k),原本 A ( k ) A(k) A(k) A ′ ( k ) A'(k) A(k)是完全对称的,现在 A ( k ) A(k) A(k)全部改了值,所以问题就解决了

E

建出所有免费走的地方之间的边,跑最短路即可
复杂度 O ( n 2 l o g 2 n ) \mathcal O(n^2log^2n) O(n2log2n)

F

按照权值从小到大加边
新增点权为某个节点到当前点路径的xor
然后建trie,加边合并的时候启发式在trie里查询
总复杂度 O ( n l o g 2 n ) \mathcal O(nlog^2n) O(nlog2n)

G

如果没有最后的交换操作的话直接贪心取段,然后将最多的段数与k比较即可
然后考虑有交换的情况,这就非常麻烦了
我们考虑 [ a 1 , a 2 ] [ b 1 , b 2 ] [ c 1 , c 2 ] [ d 1 , d 2 ] [ e 1 , e 2 ] [ f 1 , f 2 ] ⋅ ⋅ ⋅ [a_1,a_2][b_1,b_2][c_1,c_2][d_1,d_2][e_1,e_2][f_1,f_2]··· [a1,a2][b1,b2][c1,c2][d1,d2][e1,e2][f1,f2]的情况
假设我们要交换两段,我们发现左段的左端点一定是某段的左端点,右段的右端点一定是某段的右端点(否则一定能分开新的段)
假设我们现在左段左端在 x 1 x_1 x1,右段右端在 y 2 y_2 y2
我们发现若 x ≠ y x\neq y x=y则交换之后一定不成立
所以 x = y x=y x=y
于是我们相当于要把一段内部花一次交换的代价以分成更多段
我们发现只要确定第一段和最后一段的端点,中间的当成不能交换的问题做就好了
我们要把第一段和最后一段翻转,所以第一段一定要包含R,最后一段一定要包含L,然后我们通过贪心把所有可以作为第一段的右端点的点都搞出来,我们发现这些点也可以成为最后一段的左端点,考虑这些分的段,如果除了第一段与最后一段剩下大于1段的,这两段排序后将不有序,所以一定只有贪心出来的一段能继续再分,于是我们就将每一段求出最大值取max即可
这里的段的示意图 [ x k , n ] [ x k − 1 , x k ) ⋅ ⋅ ⋅ [ x 1 , x 2 ) [ 1 , x 1 ) [x_k,n][x_{k-1},x_k)···[x_1,x_2)[1,x_1) [xk,n][xk1,xk)[x1,x2)[1,x1),我们每次算一个 [ x i , x i + 1 ] [x_i,x_{i+1}] [xi,xi+1]的答案就好了
,总复杂度 O ( n ) \mathcal O(n) O(n)
下面是AC代码
题目链接

#include<cstdio>
#include<cctype>
#include<algorithm>
//#include<ctime>
#define rg register
typedef long long ll;
template <typename T> inline T max(const T a,const T b){return a>b?a:b;}
template <typename T> inline T min(const T a,const T b){return a<b?a:b;}
template <typename T> inline void mind(T&a,const T b){a=a<b?a:b;}
template <typename T> inline void maxd(T&a,const T b){a=a>b?a:b;}
template <typename T> inline T abs(const T a){return a>0?a:-a;}
template <typename T> inline void Swap(T&a,T&b){T c=a;a=b;b=c;}
//template <typename T> inline void swap(T*a,T*b){T c=a;a=b;b=c;}
template <typename T> inline T gcd(const T a,const T b){if(!b)return a;return gcd(b,a%b);}
template <typename T> inline T lcm(const T a,const T b){return a/gcd(a,b)*b;}
template <typename T> inline T square(const T x){return x*x;};
template <typename T> inline void read(T&x)
{
	char cu=getchar();x=0;bool fla=0;
	while(!isdigit(cu)){if(cu=='-')fla=1;cu=getchar();}
	while(isdigit(cu))x=x*10+cu-'0',cu=getchar();
	if(fla)x=-x;
}
template <typename T> inline void printe(const T x)
{
	if(x>=10)printe(x/10);
	putchar(x%10+'0');
}
template <typename T> inline void print(const T x)
{
	if(x<0)putchar('-'),printe(-x);
	else printe(x);
}
int n,k,a[1000001],maxplace,las=1;
int ok[1000001],tot;
void rt(const bool fla)
{
	if(fla)puts("Yes");
	else puts("Poor Simon");
	exit(0);
}
int le,aaa[1000001];
int calc2()
{
	int ma=0,an=0;
	for(int i=1;i<=le;i++)
	{
		maxd(ma,aaa[i]);
		if(i==ma)an++;
	}
	return an;
}
int len,A[1000001];
int calc1()
{
	maxplace=0;
	int ans=0,fst=0,la=1;
	for(int i=1;i<=len;i++)
	{
		maxd(maxplace,A[i]);
		if(i==maxplace)
		{
			fst++;
			if(fst!=1&&i!=len)
			{
				le=i-la+1;
				for(int j=1;j<=le;j++)aaa[le-j+1]=A[la+j-1]-la+1;
				maxd(ans,calc2());
			}
			la=i+1;
		}
	}
	return ans+min(fst,2);
}
int check(int l,int r)
{
	len=r-l+1;
	for(int i=1;i<=len;i++)A[len-i+1]=a[l+i-1]-l+1;
	return calc1()-1;
}
int main()
{
	read(n),read(k);
	for(int i=1;i<=n;i++)read(a[i]);
	for(int i=1;i<=n;i++)
	{
		maxd(maxplace,a[i]);
		if(i==maxplace)ok[i]=1,tot++;
	}
	if(tot>=k)rt(1);
	for(int i=1;i<=n;i++)
		if(ok[i])
		{
			if(tot+check(las,i)>=k)rt(1);
			las=i+1;
		}
	rt(0);
	return 0;
}

H

我们发现只要赢的次数最多,直接贪心即可,两行代码足矣

I

大概是经典的FFT题目,先转化为原根求和,变成加法问题后直接用FFT做卷积即可

J

我们发现,我们要求的是最长不上升子序列即 0 ⋅ ⋅ ⋅ 01 ⋅ ⋅ ⋅ 1 0···01···1 0011形式
要求所有的 ( s u m 0 + s u m 1 ) s u m 0 = s u m 0 2 + s u m 1 s u m 0 (sum_0+sum_1)sum_0=sum_0^2+sum_1sum_0 (sum0+sum1)sum0=sum02+sum1sum0
考虑枚举最右边的一个 0 0 0
我们要求的是 ∑ s u m 1 \sum sum_1 sum1,并且要满足这是最右边的 0 0 0,如果右边有更多就不优
考虑dp, f i , j , g i , j f_{i,j},g_{i,j} fi,j,gi,j分别表示到第i个数,1的数量,方案数推完即可,复杂度 O ( n 2 ) \mathcal O(n^2) O(n2)(容易发现 1 1 1的数量要一直大于 0 0 0的数量)
再考虑求左侧的情况,要求 ∑ s u m 0 \sum sum_0 sum0非常方便,同理即可(不过这里容易发现 0 0 0的数量要一直大于等于 1 1 1的数量)
然后求 ∑ s u m 0 2 \sum sum_0^2 sum02好像也没啥区别,贡献的时候有个平方就好了
然后就做完了
复杂度 O ( n 3 ) \mathcal O(n^3) O(n3)

K

容易发现,对于原序列,每一个左括号都有相应的有括号进行匹配,对于任何截取的一段 l , r l,r l,r,括号匹配的要求是不变的,所以直接维护每个左括号匹配的右括号位置即可,每次询问用一个区间max即可
)厉害的人可以搞一个 O ( n ) − O ( 1 ) \mathcal O(n)-\mathcal O(1) O(n)O(1)rmq

L

根据扩展欧几里得可知x,y的通解
现在相当于求 a x ( b + x ) + c y ( d + y ) ax(b+x)+cy(d+y) ax(b+x)+cy(d+y)
然后因为给出的系数都很小,好像枚举就好了

结语

1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看REAdMe.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看REAdMe.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看READme.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 、 1资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看READmE.文件(md如有),本项目仅用作交流学习参考,请切勿用于商业用途。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值