2021-07-02 07:45~11:45
之前真的是比赛打太少了,做的很不顺。
T1
Floyed带走100pts
T2
想到了鸽巢原理,却没想到对前缀和用鸽巢原理。想到了就是sbt了。。。赛时爆搜50pts
T3
开始题看错了结果写的有30pts,后来题看对了贪心0pts
想写这篇博客也就是因为T3吧。。。
这场模拟赛的AKer——ATue说:“求最小的最大,求最大的最小,当然是二分啊。”说的十分有理,但先前我脑海里却没有这样的思想,记得 [NOIP2018]赛道修建 那题也是如此。
想到是二分了,关键就在于怎么判断二分的这个点可行与否了
第一种:逆推。能到达a[x]的范围为[a[x]-mid,a[x]+mid] 。其实思维含量也挺高的QwQ
28ms 2.24MB C++ 866B
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
| #pragma GCC optimize("Ofast") #include <bits/stdc++.h> using namespace std; inline int gin(){ int s=0,f=1; char c=getchar(); while(c<'0' || c>'9'){ if(c=='-') f=-1; c=getchar(); } while(c>='0'&&c<='9'){ s=(s<<3)+(s<<1)+(c^48); c=getchar(); } return s*f; }
const int N=1e5+5; int n; int a[N];
bool check(int mid){ if(abs(a[2]-a[1])>mid) return 0; int l=a[n]-mid,r=a[n]+mid; int x=n-1; while(x>2){ if(l<=a[x] && a[x]<=r){ l=a[x]-mid; r=a[x]+mid; } else { l=max(l,a[x]-mid); r=min(r,a[x]+mid); } x--; } if(l<=a[1] && a[1]<=r) return 1; if(l<=a[2] && a[2]<=r) return 1; return 0; }
signed main(){ n=gin()+2; for(int i=1;i<=n;i++) a[i]=gin(); int l=1,r=1e9+1; while(l<r){ int mid=l+r>>1; if(check(mid)) r=mid; else l=mid+1; } printf("%d\n",l); return 0; }
|
ATue的st表判断,好强QwQ
132ms 22.07MB C++ 1224B
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
| #pragma GCC optimize("Ofast") #include <bits/stdc++.h> using namespace std; inline int gin(){ int s=0,f=1; char c=getchar(); while(c<'0' || c>'9'){ if(c=='-') f=-1; c=getchar(); } while(c>='0'&&c<='9'){ s=(s<<3)+(s<<1)+(c^48); c=getchar(); } return s*f; }
const int N=1e5+5; int n,st[N],top,a[N],lg[N],mx[N][25],mn[N][25];
inline int getmx(int l,int r){ int k=lg[r-l+1]; return max(mx[l][k],mx[r-(1<<k)+1][k]); }
inline int getmn(int l,int r){ int k=lg[r-l+1]; return min(mn[l][k],mn[r-(1<<k)+1][k]); }
bool check(int mid){ st[top=1]=1,st[++top]=2; for(int i=3;i<=n;i++){ int j=st[top]; while(top){ if(a[j]-getmn(j,i)<=mid && getmx(j,i)-a[j]<=mid) break; else j=st[--top]; } if(!top) return 0; st[++top]=i; } return 1; }
signed main(){ n=gin()+2; lg[0]=-1; for(int i=1;i<=n;i++) mx[i][0]=mn[i][0]=a[i]=gin(),lg[i]=lg[i>>1]+1; for(int j=1;(1<<j)<n;j++) for(int i=1;i+(1<<j)-1<=n;i++) mx[i][j]=max(mx[i][j-1],mx[i+(1<<j-1)][j-1]),mn[i][j]=min(mn[i][j-1],mn[i+(1<<j-1)][j-1]); int l=abs(a[2]-a[1]),r=1e9+1; while(l<r){ int mid=l+r>>1; if(check(mid)) r=mid; else l=mid+1; } printf("%d\n",l); return 0; }
|
T4
6^n加剪枝加Ofast能过诶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
| #pragma GCC optimize("Ofast") #include <bits/stdc++.h> using namespace std; inline int gin(){ int s=0,f=1; char c=getchar(); while(c<'0' || c>'9'){ if(c=='-') f=-1; c=getchar(); } while(c>='0'&&c<='9'){ s=(s<<3)+(s<<1)+(c^48); c=getchar(); } return s*f; }
const int N=1<<14; int cnt[N],f[N],ans[N],p[N],k,n;
inline bool cmp(int x,int y){ return cnt[x]<cnt[y]; } void init(){ for(int i=0;i<k;i++) cnt[i]=cnt[i>>1]+(i&1),p[i]=i,ans[i]=-1; sort(p,p+k,cmp); return; }
signed main(){ n=gin(); k=1<<n; init(); for(int i=0;i<k;i++) scanf("%1d",f+i); for(int i=0;i<k;i++){ for(int u=0;u<k;u++){ if(~ans[u]) continue; int s=(k-1)^p[i]; if(f[u]!=f[u&p[i]]) continue; bool flag=1; for(int v=s;v;v=(v-1)&s) if(f[u]!=f[u&p[i]|v]){ flag=0; break; } if(flag) ans[u]=cnt[p[i]]; } } for(int i=0;i<k;i++) printf("%d ",ans[i]); return 0; }
|
Author:
Push_Y
Permalink:
https://wzsyyh.github.io/post/WZOIR1/
License:
Copyright (c) 2019 CC-BY-NC-4.0 LICENSE
Slogan:
I'll make IT!