2025ccpc南昌邀请赛感想+补题
比赛前去了81纪念馆和滕王阁,必须说江西的风景还是不错的,不过可惜的是作为一个江西人没有吃到足够辣的江西菜
赛前一晚做梦梦到比赛打炸了,然后还有另一个比赛也忘记打了,回去被同学鞭尸给我吓醒了,谁懂醒来还在酒店床上的救赎感
还好梦是反的,最后7题拿下第一个金牌,可惜最后封榜后没有过题
补题链接https://qoj.ac/contest/2521
L
签到题,没什么好说的
G
同样是签到题
A
队友打的,不记得了
K
所有菜品根据模4可分为4类,0,1,2,3
策略是先把0上完,然后上3131...直到3或者1用完
如果剩了3,可以循环上332,如果剩1就循环上211,如果2不够就没有答案返回no
最后剩的2就222的上,时间复杂度O(n)
H
肯定只有n次加珠子,先把这n次加上,得到数组1,2,...,n
把第二种操作插入这n个操作中,本质就是一个单点加1再对这个点之后的某个后缀区间加1
把目标数组ai-i,得到剩下的就是需要用操作2补全的量,如果有负值直接输出no
从左往右贪心想最少需要多少次操作即可,时间复杂度O(n)
C
如果对于[L,R]的虫洞,能快速判断它们能否被划分成不超过k组,就能用双指针解题
赛时突然想到的假设,后来可以证明,把一个虫洞看成一个区间加1操作,如果最后没有点大于k,就说明这些虫洞可以被划分成不超过k组
最后线段树+双指针一发过,时间复杂度O(nlogn)
B
感觉n比较大的时候很难出现一个人赢所有人或者输所有人的情况
于是手算了一下随机选两个人u和v,u对v是k间接战胜的概率
\(P(k=0)=1/2,P(k=1) = (1-(3/4)^{n-2})/2\)
可以看出来当n很大时,k = 0和k = 1的概率加起来已经很接近1了,那么就不需要考虑其他k>1的情况
假定分界点是n = 100,当n<=100时使用floyd算法预处理多源最短路,时间复杂度O(n^3)
当n>100时遍历所有点对(u,v),如果u赢了v,u对v是0间接胜利,v对u则是1间接胜利,时间复杂度O(n^2)
写法很简单,从思考到ac花的时间感觉不超过20min,最后还是1发ac,感觉这次状态真的不错
赛时过的就这些,其余待补
补:
E
赛时想到的是确定一条线,可以用前缀和快速求这条线左右两边的同色积之和,但是这样是O(n^2 * k)复杂度的,过不了
后来看了题解,假设要求4个点的积为\(a_i * a_j * a_k * a_l ,其中i<j<k<l,且c_i = c_k,c_j = c_l\)
那么可以遍历\(a_k\),用前缀和处理其他几项的积,再遍历每种颜色计算即可,时间复杂度O(nk)
点击查看代码
#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
#define lowbit(x) = ((x)& - (x))
#define rep(a,b,c) for(int a=b;a<=c;a++)
#define per(a,b,c) for(int a=b;a>=c;a--)
#define x first
#define y second
using namespace std;
typedef long long ll;
const int N = 5e5+4;
const ll mod = 998244353;
ll n,k;
ll c[N],a[N];
ll s[N][103],t[N][103],p[103][103];
void print(){
cout<<"s:\n";
rep(i,1,n){
rep(j,1,k)cout<<s[i][j]<<' ';
cout<<'\n';
}
cout<<"t:\n";
rep(i,1,n){
rep(j,1,k)cout<<t[i][j]<<' ';
cout<<'\n';
}
cout<<"p:\n";
rep(i,1,k){
rep(j,1,k)cout<<p[i][j]<<' ';
cout<<'\n';
}
}
int main(){
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
cin>>n>>k;
rep(i,1,n)cin>>c[i];
rep(i,1,n)cin>>a[i];
rep(i,1,n){
rep(j,1,k){
s[i][j] = s[i-1][j];
if(c[i] == j)s[i][j] = (s[i][j] + a[i])%mod;
}
}
per(i,n,1){
rep(j,1,k){
t[i][j] = t[i+1][j];
if(c[i] == j)t[i][j] = (t[i][j] + a[i])%mod;
}
}
ll ans = 0;
rep(i,1,n){
rep(j,1,k){
ans = (ans + a[i] * p[j][c[i]] % mod * t[i+1][j] % mod)%mod;
}
rep(j,1,k){
if(j != c[i]){
p[c[i]][j] = (p[c[i]][j] + a[i] * s[i-1][j] % mod)%mod;
}
}
}
//print();
cout<<ans<<'\n';
return 0;
}

浙公网安备 33010602011771号