集训Day9~11总结
专题:
Day \(9\) 图论(一):
1.专题结束前做了 \(5\) 道(\(F\) 没调完)
2.补题 \(2\) 道
Day \(10\) 图论(二):
1.专题结束前做了 \(0\) 道(\(CF\) 炸了一道没交上😭😭😭)
2.补题 \(3\) 道
Day \(11\) 图论(三):
1.专题结束前做了 \(6\) 道
2.补题 \(1\) 道
模拟赛四游记
总分:\(100pts\) 排名:\(106\)
\(T1\):\(100pts\)
\(T1\) 很简单,一个调和级数的时间复杂度就过了
\(T2\):\(0pts\)
做法是 \(O(5n)\) 枚举每一位修改成什么,然后用前缀和 \(O(1)\) 维护修改后的值,但是一些细节没有考虑到,赛后也没改对,成功爆零。
而且我当时交上去的代码显示是 \(RE\),因为我用到了 \(a_{5,i}\),然后我数组开的是 \(a_{4,N}\),本地编译居然没报错!!!还能过样例???!!!😱😱😱😡😡😡
正确做法:如果要把一位改大,那么肯定是修改最前面的那一位,对后面的影响最小,如果改小,那么肯定是修改最后面的一位,尽量把贡献增大,这算是一个贪心的思路,只需要 \(5\times 5\) 枚举 \(i\) 字母改成 \(j\),然后预处理,每个字母出现的第一个位置和最后一个位置,每次 \(O(n)\) 算答案,时间复杂度 \(O(25n)\)。
教训:要多想一下细节的问题,要考虑全面,不要指望样例能测出来,样例很水。。。
\(T3\):\(0pts\)
\(T3\) 一直在想正解,因为推出来一个可以 \(DP\) 的式子,但是时间复杂度是不对的,所以就像能不能再推一个公式调和级数的求出答案,赛后发现不能,推的公式时间复杂度必须是\(O(n^2)\),\(O(n)\) 是不对的,最后暴力也没打完,样例都没过就交上去了,赛后 \(1min\) 后,提交了暴力 \(30pts\),暴力分又没拿到,\(T4\) 也没来得及看。
正确做法:用到了隔板法,考虑求出以 \(i\) 结尾的方法数,然后累加
细节看代码:
代码
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+5,mod=998244353;
int fact[2*N],infact[2*N];
int qmi(int a,int b){
int res=1;
while(b){
if(b&1) res=1ll*res*a%mod;
b>>=1;
a=1ll*a*a%mod;
}
return res;
}
int C(int n,int m){
if(n<m) return 0;
if(!m) return 1;
return 1ll*fact[n]*infact[m]%mod*infact[n-m]%mod;
}
int main(){
int n,m;
scanf("%d%d",&n,&m);
fact[0]=infact[0]=1;
for(int i=1;i<2*N;i++){
fact[i]=1ll*fact[i-1]*i%mod;
infact[i]=1ll*infact[i-1]*qmi(i,mod-2)%mod;
}
long long ans=0;
for(int i=1;i<=m;i++){
int x=i,sum=1;
for(int j=2;j<=x/j;j++){
int cnt=0;
if(x%j==0){
while(x%j==0){
x/=j;
cnt++;
}
sum=1ll*sum*C(n+cnt-1,n-1)%mod;
}
}
if(x>1) sum=1ll*sum*C(n,n-1)%mod;
ans=(ans+sum)%mod;
}
printf("%lld",ans);
return 0;
}
$T4:\(0pts\)
赛时只简单看了一眼,没来得及写,但这道题暴力还像不太好写。
正确做法:
交换操作有一个很巧妙的处理方式,就是把每个 \(a_{i}\) 加上 \(i\),这样交换操作就可以直接交换,不用 \(+1\) 和 \(-1\) 了,再把 \(b\) 数组同样操作,然后找到每个 \(a\) 数组在 \(b\) 数组中的位置 \(c_{i}\),直接求逆序对的数量就可以,如果找不到就直接输出 \(-1\),细节看代码。
代码
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+5;
int a[N],b[N],c[N],tr[N];
map<int,queue<int> > mp;
inline int lowbit(int x){
return x&-x;
}
inline void add(int x,int c){
for(int i=x;i<N;i+=lowbit(i)){
tr[i]+=c;
}
}
inline int sum(int x){
int res=0;
for(int i=x;i>=1;i-=lowbit(i)){
res+=tr[i];
}
return res;
}
inline int query(int l,int r){
return sum(r)-sum(l-1);
}
int main(){
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
a[i]+=i;
}
for(int i=1;i<=n;i++){
scanf("%d",&b[i]);
b[i]+=i;
mp[b[i]].push(i);
}
for(int i=1;i<=n;i++){
if(!mp[a[i]].size()){
printf("-1");
return 0;
}
c[i]=mp[a[i]].front();
mp[a[i]].pop();
}
long long ans=0;
for(int i=1;i<=n;i++){
ans+=query(c[i]+1,n);
add(c[i],1);
}
printf("%lld",ans);
return 0;
}
总结:这次模拟赛是一个很悲伤的模拟赛QAQ,不仅 \(T2\) 又双叒叕没 \(A\),\(T3\ T4\) 还都爆零了,居然还排到了 \(100\) 多名T˄T,不要执着于死磕正解,也不要对 \(T2\) 过于自信,觉得能过。

浙公网安备 33010602011771号