8月2日CSP-S模拟赛赛后总结
8 月 2 日 模拟赛 赛后总结 2024 年 8 月 2 日 b y u h w 177 p o 8月2日 \ \ 模拟赛 \ \ 赛后总结 \\ 2024年8月2日 \\ by \ \ \ uhw177po 8月2日 模拟赛 赛后总结2024年8月2日by uhw177po
一、做题情况
-
第一题比赛 20 p t s 20pts 20pts ,赛后 A C AC AC
-
第二题比赛 0 p t s 0pts 0pts ,赛后 A C AC AC
-
第三题比赛 0 p t s 0pts 0pts ,赛后 A C AC AC
-
第四题比赛 0 p t s 0pts 0pts ,赛后 50 p t s 50pts 50pts
-
比赛得分 20 / 400 p t s 20/400 \ pts 20/400 pts ,赛后补题 350 / 400 p t s 350 / 400 \ pts 350/400 pts
二、比赛概况
这场模拟赛比较难,T1读了题好久都没有想出解法,想出解法了又被自己给 H a c k Hack Hack 掉了。(实际当时有一种解法是对的)当时就只有 90 min。T2还好,可是贪心没想出(因为当时以为 二分答案,check 死活想不出)T3、T4都读了一遍,发现自己不会做,只好骗分。死得很惨。
三、题解报告
T1:
题面:
做法:
前缀和 板子题,序列可为山峰、递增、递减,然后进行前缀和,轻松做出。
附:AC代码
#include <bits/stdc++.h>
#define int long long
#pragma G++ optimize (2)
#pragma G++ optimize (3)
using namespace std ;
int n , T , a [5000010] , b [5000010] , c [5000010] , x , y ;
signed main () {
ios::sync_with_stdio (false) ;
cin.tie (NULL) ; cout.tie (NULL) ;
freopen ("hot.in" , "r" , stdin) ;
freopen ("hot.out" , "w" , stdout) ;
cin >> n >> T ;
a [n + 1] = 2e9 ; a [0] = -1 ;
x = 0 ;
for (int i = 1 ; i <= n ; i ++) {
cin >> a [i] ;
if (a [i] > a [i - 1]) x = i ;
b [i] = x ;
}
for (int i = n ; i >= 1 ; i --) {
if (a [i] > a [i + 1]) x = i ;
c [i] = x ;
}
while (T --) {
cin >> x >> y ;
cout << (c [x] >= b [y] ? "Y\n" : "N\n") ;
}
return 0 ;
}
T2:
题面:
做法:
一道 贪心,需要自己推出。
附:AC代码
#include <bits/stdc++.h>
#define int long long
#pragma G++ optimize (2)
#pragma G++ optimize (3)
using namespace std ;
int n , a [100010] , x , p , ans ;
signed main () {
ios::sync_with_stdio (false) ;
cin.tie (NULL) ; cout.tie (NULL) ;
freopen ("divide.in" , "r" , stdin) ;
freopen ("divide.out" , "w" , stdout) ;
cin >> n ; // f*ck €€£
for (int i = 1 ; i <= n ; i ++) cin >> a [i] ;
x = a [n] ;
for (int i = n - 1 ; i >= 1 ; i --)
if (a [i] > x) {
p = (a [i] - 1) / x ;
ans += p ;
x = a [i] / (p + 1) ;
}
else x = a [i] ;
cout << ans ;
// And more money
return 0 ;
}
T3:
题面:
做法:
线性dp,可知转移方程式 d p [ i 1 ] = max ( d p [ i 1 − 2 ] + max ( 0 , a [ i ] [ i 1 − 1 ] + a [ i ] [ i 1 ] ) dp[i1]=\max(dp[i1-2]+\max(0,a[i][i1-1]+a[i][i1]) dp[i1]=max(dp[i1−2]+max(0,a[i][i1−1]+a[i][i1]),可以做出。
附:AC代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef unsigned int ui;
typedef long double ld;
int n,m,a[1005][1005],dp[1005],ans;
int main(){
freopen("tunnel.in","r",stdin);
freopen("tunnel.out","w",stdout);
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) for(int i1=1;i1<=m;i1++) scanf("%d",&a[i][i1]);
for(int i=1;i<=n;i++)
{
for(int i1=2;i1<=m;i1++) dp[i1]=max(dp[i1-2]+max(0,a[i][i1-1]+a[i][i1]),dp[i1-1]);
ans+=dp[m];
}
dp[1]=0;
for(int i=1;i<=m;i++)
{
for(int i1=2;i1<=n;i1++) dp[i1]=max(dp[i1-2]+max(0,a[i1-1][i]+a[i1][i]),dp[i1-1]);
ans+=dp[n];
}
printf("%d",ans);
return 0;
}
T4:
题面:
做法:
十分复杂,正解线段树,但不会做。
50 p t s 50 pts 50pts:随便搓一下。
附:AC代码
#include<bits/stdc++.h>
using namespace std;
const int Max_N=2e5;
int n,cnt,a[Max_N+5],pos[Max_N+5],nxt[Max_N+5],R[Max_N+5],rp[Max_N+5];
struct Tree{ int l,r,Mn; } A[Max_N*4+5];
vector<int> p[Max_N+5];
void Build(int x,int l,int r){
A[x].l=l; A[x].r=r; A[x].Mn=n+1;
if(l==r) return ;
Build(x<<1,l,(l+r)>>1);
Build((x<<1)|1,((l+r)>>1)+1,r);
}
int Ask(int x,int k){
if(k<=A[x].l&&k<=A[x].Mn) return A[x].r;
if(A[x].l==A[x].r) return 0;
if(k<=A[x<<1].r){
int t=Ask(x<<1,k);
if(t==A[x<<1].r){
int w=Ask((x<<1)|1,k);
if(w) return w;
else return t;
} else return t;
}
return Ask((x<<1)|1,k);
}
void Add(int x,int p,int w){
if(A[x].l==A[x].r){
A[x].Mn=w;
return;
}
if(p<=A[x<<1].r) Add(x<<1,p,w);
else Add((x<<1)|1,p,w);
A[x].Mn=min(A[x<<1].Mn,A[(x<<1)|1].Mn);
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&a[i]),p[a[i]].push_back(i),rp[i]=p[a[i]].size();
for(int i=n;i>=1;i--) pos[i]=n+1;
for(int i=n;i>=1;i--){
nxt[i]=pos[a[i]];
pos[a[i]]=i;
}
Build(1,1,n);
long long ans=n;
for(int i=n;i>=1;i--){
if(nxt[i]==n+1||i+1>nxt[i]-1||R[i+1]<nxt[i]-1||a[i+1]!=a[nxt[i]-1]) R[i]=i;
else {
int rans=R[nxt[i]];
rans=min(rans,Ask(1,nxt[i]));
if(rans==0) R[i]=nxt[i],++ans;
else {
int x=upper_bound(p[a[i]].begin(),p[a[i]].end(),rans)-p[a[i]].begin();
R[i]=p[a[i]][x-1]; ans+=x-rp[i];
}
}
if(nxt[i]<=n) Add(1,nxt[i],i);
}
printf("%lld\n",ans);
return 0;
}
四、赛后总结
死得太惨了。(fuck €€£)