集训Day17~19总结

专题:

Day \(17\) dp(一):

1.做了 \(5\)

2.补题 \(1\)

Day \(18\) dp(二):

1.做了 \(2\)

Day \(19\) dp(三):

1.做题 \(3\)

2.补题 \(2\)

模拟赛七游记

总分:\(180pts\) 排名:\(36\)

挂分:至少 \(100pts\)

\(T1\)\(0pts\)

\(8:13\) 开始看 \(T1\),这是一道很悲惨的题,比赛结束后点开一看,第一个点就 \(TLE\),我用了 \(map\),赛后开了 \(unordered\)_\(map\) 交上去,发现只有第 \(50\) 个点 \(TLE\) 了,但是在 \(AT\) 上过了,后来发现 \(AT\) 的时间限制是 \(2s\),而模拟赛是 \(1s\),我的时间复杂度是 \(n^2\ log\ n^2\),枚举的 \(a_{i}\ xor\ b_{j}\) 的值,\(1s\) 跑不过去,赛后才发现只需要枚举 \(a_{1}\ xor\ b_{i}\) 的值就可以了。虽然一直在算时间复杂度,怕超时,但还是超时了。。。

总结:时间复杂度一定要算好

\(T2\)\(100pts\)

\(9:11\) 开始看\(T2\)\(T2\) 是一道贪心题,可以发现一个性质,如果不能恰好两两配对,那么一定有两个颜色是奇数,一个颜色是偶数,那么答案就是两个奇数颜色中差的最小值和样例 \(1\) 这种情况的最小值。这次的样例居然还给出了一种情况!但是由于我写了 \(113\) 行的代码一遍就过编译了,并且还过样例了,我十分的担心挂分,但犹豫样例依然很水,测不出来,自己的 \(hack\) 也没问题,于是盯代码盯了半天,发现出了一个错误!!!🎉🎉🎉

if(j1<=n)//应该是if(j1<=lenaa)
if(j2<=n)//应该是if(j2<=lenbb)

总结:要认真检查代码,像这次一样。赛后特意交了一下错误代码,发现是 \(0pts\)!😱😱😱

\(T3\)\(30pts\)

\(10:44\) 开始看 \(T3\)\(n=1\) 的情况是一个很简单的构造,\(30pts\) 很容易就得到了,但是又重蹈了之前模拟赛的覆辙\(hack\) 掉正解,当时就想如果 \(2000,2001,2002,2010\) 这样构造不能保证每一位的数的个数不超过 \(n\),如果超过了,那后面的构造就都不对了,但后来发现 \(2\) 开头的数一定只有 \(n\) 个,怎么会超过呢,这次运气没有那么好,并没有想出第二种解法,还剩 \(30min\) 左右,虽然觉得 \(T3\) 再想想应该能想出来。但是看了眼 \(T4\) 觉得性价比更高,\(50pts\) 很好拿,就没有冒险去想 \(T3\)但貌似 \(A\)\(T3\) 性价比更高。

总结:要仔细想一想,千万不要再 \(hack\) 掉正解。。。

\(T4\)\(50pts\)

\(11:26\) 开始看 \(T4\),第一眼想写二分答案,写完后一测样例,发现不对,答案没有单调性,然后开始打暴力,\(50pts\) 成功到手。但赛时想到了如果 \(k\) 足够大,可以把 \(a_{1}\)\(a_{n}\) 都变成相同的数,然后写了一个特判。

正解:从大到小枚举因数 \(x\),然后把 \(a\) 的值分段,分成 \(1\) ~ \(x\)\(x+1\) ~ \(2x...\),用前缀和去预处理,时间复杂度是调和级数的。

总结:要善于观察数据范围,发现一些特殊性质。

代码
#include<bits/stdc++.h>
using namespace std;
const int N=3e5+5;
int a[N],b[N];
long long s[N];
int main(){
	freopen("wowogcd.in","r",stdin);
	freopen("wowogcd.out","w",stdout);
	int n,mx=0;
	long long k,sum=0;
	scanf("%d%lld",&n,&k);
	for(int i=1;i<=n;i++){
		scanf("%d",&a[i]);
		sum+=a[i];
		mx=max(mx,a[i]);
		b[a[i]]++;
		s[a[i]]+=a[i];
	}
	if(k>=1ll*mx*n-sum){
		printf("%lld",(sum+k)/n);
		return 0;
	}
	for(int i=1;i<=mx;i++){
		b[i]+=b[i-1];
		s[i]+=s[i-1];
	}
	for(int i=mx;i>=1;i--){
		long long ans=0;
		int f=1;
		for(int j=i;;j+=i){
			if(j>mx) ans+=1ll*(b[mx]-b[j-i])*j-(s[mx]-s[j-i]);
			else ans+=1ll*(b[j]-b[j-i])*j-(s[j]-s[j-i]);
			if(ans>k){
				f=0;
				break;
			}
			if(j>=mx) break;
		}
		if(f){
			printf("%d",i);
			return 0;
		}
	}
	return 0;
}

总结:

1.要分配好时间,部分分有的时候很重要,注重得分的性价比。

2.千万不要挂分❗❗❗

补题:4/4

集训结束前的最后一次总结会😭😭😭

posted @ 2026-08-15 08:21  yushihan  阅读(9)  评论(0)    收藏  举报