联合省选2025游记

赛前
正式比赛最摆烂的一集。
还是一样的赛前模板,写的题比 NOIP 的题少太多了。

对比 NOIP:

省选赛前饺子一中发了咖啡和士力架。
赛时
Day 1
先开 T1,感觉是个 妙妙性质题,感觉判断一个数是否可能为中位数可以通过一个远古 trick 来解决,也就是把小于这个数的数看成 \(-1\),等于这个数的可以看成 \(-1,0,1\) 的任意一种,而大于这个数的可以看成 \(1\)。
但他能取得数是一段区间,于是就不会了。
然后又会了,感觉能等于这个数的话我们选 \(-1,0,1\) 感觉非常优秀,剩下的已经确定是 \(-1\) 还是 \(1\) 了。
于是我们就得到了 性质B 的做法:离散化后维护每个区间的左右端点,之后枚举每个可能的答案,然后把新加入的线段记录一个值叫 valt 表示有多少个任意取值的,把出去的加入 valf,最初都在 valz,之后判断是否合法即可。
但我要想正解,我们考虑加入 valt 的一定是数量最多的,然后我们把 valf 和 valz 改成一个区间的形式,记录他能取到的最小值和最大值,这样会构成两个区间,看看这两个区间经过 valt 的调整后是否能相交就做完了。
但我这个想法从 \(9:21\) 开写跳到 \(11:12\) 才过拍,细节巨多:
- 离散化时要给右端点加 \(1\),这样才是一个实打实的区间。
- 如果
valt=0的话即使两区间相交了也不行。
写代码十分钟,调代码两小时
拿下 T1 大样例后拿着性质 AB 的代码拍了拍,拍了一万组,开了 T2:
感觉一眼不会,只能打暴力和性质了,先拿下了暴力的二十分,之后开了 T3,同样码了 \(O(n!)\) 的做法。
之后就去思考了无修改的性质,感觉可以按照 \(dfn\) 重新编号后再跑,但感觉码起来非常困难,还要维护 st表 之类的才能进行区间查询。
最后 \(Day 1=100+20+8=128\),遗憾离场。
upd:2025.3.11:
自测没挂分。
Day 2
来到我的位置是才发现昨天带的东西一点没吃,于是先进行了一个士力架的吃,之后开了 T1:
看到 T1,我会一个暴力跳的做法,之后注意到有一个性质是 \(a,b\) 单调递增,感觉可以二分,于是暴力跳,暴力修改,就得到了一个不知道能拿多少分的我的赛事代码:
//I do think Nothing is Required but bruteforce
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define Air
namespace io{
int read(){
int t=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-f;ch=getchar();}
while(ch>='0'&&ch<='9'){t=t*10+ch-'0';ch=getchar();}
return t*f;
}
void write(int x){
if(x<0){putchar('-');x=-x;}
if(x>=10)write(x/10);
putchar(x%10+'0');
}
}
using namespace io;
int n;
const int N=3e5+10;
int TCS;
struct node{
int st,ed,tim;
int id;
friend bool operator<(node x,node y){
return x.tim<y.tim;
}
}box[N];
int a[N];
int move(int st,int ed,int id){
if(st==ed)return 0;
if(st<ed){//right
int idd=upper_bound(a+1,a+1+n,ed)-a-1;
if(idd==id){
a[id]=ed;
return ed-st;//direct move
}
int dis=idd-id;
int step=move(a[idd],ed+dis,idd);
for(int i=id;i<idd;i++){
step+=(i-id)+ed-a[i];
a[i]=(i-id)+ed;
}
return step;
}
else{
int idd=lower_bound(a+1,a+1+n,ed)-a;
if(idd==id){
a[id]=ed;
return st-ed;//direct move
}
int dis=id-idd;
int step=move(a[idd],ed-dis,idd);
for(int i=id;i>idd;i--){
step+=a[i]-ed+(id-i);
a[i]=ed-(id-i);
}
return step;
}
}
void work(){
n=read();
for(int i=1;i<=n;i++){
box[i]={read(),read(),read(),i};
a[i]=box[i].st;
}
sort(box+1,box+1+n);
if(TCS==5||TCS==9||TCS==13||TCS==19||TCS==20){//16pts
int kk=0;
for(int i=1;i<=n;i++){
kk+=box[i].ed-box[i].st;
if(kk>box[i].tim){
puts("No");
return ;
}
}
puts("Yes");
return ;
}
int kk=0;
for(int i=1;i<=n;i++){
kk+=move(a[box[i].id],box[i].ed,box[i].id);
if(kk>box[i].tim){
puts("No");
return ;
}
}
puts("Yes");
return ;
}
signed main(){
#ifdef Air
freopen("move.in","r",stdin);
freopen("move.out","w",stdout);
#endif
TCS=read();
int T=read();
while(T--){
work();
}
//tai kun nan le
return 0;
}
之后我去考虑了优化,感觉像区间修改等差数列,但如何二分,我这里不会维护了,感觉不会处理连环的情况,之后就放弃了,打了 T2、T3 的暴力,发现 T2 暴力无法通过第二个小样例,边红边调,最终拼尽全力无法战胜。
估分:
\(Day2=[44,80]+0+8=?\)
upd:25.3.11
自测:
\(Day2=60+4+8=72\)
甚至反向挂分。
赛后
在洛谷上订了 D2T1 感觉非常妙,原来可以维护 \(ed_i-i\) 我太菜了。

浙公网安备 33010602011771号