[游记]2022年多校冲刺NOIP联训测试5-2022.7.25
今日份智障错误:看错比赛时间+没有删 $\operatorname{freopen}$
然后就爆炸了,$190/400$
A. 旅行日记
显然的一个贪心,但是要注意一些奇奇怪怪的条件
不难发现,设当次的时间是 $t[i]$ ,高度是 $h[i]$
那么在这次和上次之间最高能到达的高度就是 $\max{(h[i],h[i-1])}+\dfrac{(t[i]-t[i-1]-\left\vert h[i]-h[i-1]\right\vert ))}{2}$
注意处理第一个和第 $n$ 个的情况否则会挂到 $80$ 分,比如他有可能在第一天到了一个比较高的高度然后一直在走下坡路
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<cstdio> #include<cstring> #include<algorithm> #include<string> #define int long long #define WR WinterRain using namespace std; const int WR=1001000,INF=1099511627776; int n,m; int t[WR],h[WR]; int read(){ int s=0,w=1; char ch=getchar(); while(ch>'9'||ch<'0'){ if(ch=='-') w=-1; ch=getchar(); } while(ch>='0'&&ch<='9'){ s=(s<<3)+(s<<1)+ch-48; ch=getchar(); } return s*w; } signed main(){ n=read(),m=read(); t[1]=read(),h[1]=read(); int maxx=t[1]-1+h[1]; for(int i=2;i<=m;i++){ t[i]=read(),h[i]=read(); maxx=max(h[i],maxx); if(abs(h[i]-h[i-1])>t[i]-t[i-1]){ printf("IMPOSSIBLE"); return 0; } maxx=max(maxx,max(h[i],h[i-1])+(t[i]-t[i-1]-abs(h[i]-h[i-1]))/2); } printf("%lld",maxx); return 0; }
B. 运动
这,一开始我考虑了用线段树维护最大最小值,然后移动两个指针维护区间左右端点
具体一点就是类似莫队,先让右端点指针无限右移到差值大于 $k$ 然后让左端点右移 $1$ ,直到右端点到达 $n$ 为止
然鹅时间复杂度是 $\Theta(Cn\log n)$ ,$C$ 是一个理论上小于等于 $4$ 的常数
然鹅最大数据三百万不是特别可过,因此我向来会被卡,这次也被卡成了 $90$ 分
代码被一次突如其来的停电吃了,于是更新了一版单调栈做法,思路是一样的但复杂度变为 $\Theta(n)$
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<cstdio> #include<cstring> #include<algorithm> #include<string> #define int long long #define WR WinterRain using namespace std; const int WR=5001000,INF=2147483647; int n,k; int a[WR]; int que1[WR],hd1,sze1; int que2[WR],hd2,sze2; int read(){ int s=0,w=1; char ch=getchar(); while(ch>'9'||ch<'0'){ if(ch=='-') w=-1; ch=getchar(); } while(ch>='0'&&ch<='9'){ s=(s<<3)+(s<<1)+ch-48; ch=getchar(); } return s*w; } signed main(){ k=read(),n=read(); for(int i=1;i<=n;i++) a[i]=read(); hd1=hd2=1;a[0]=a[1]; int ans=1,pos=1; for(int i=1;i<=n;i++){ while(que1[hd1]<i&&hd1<=sze1) ++hd1; while(que2[hd2]<i&&hd2<=sze2) ++hd2; while(pos<=n){ int maxx=-INF,minn=INF; if(hd1<=sze1) maxx=a[que1[hd1]]; maxx=max(maxx,a[pos]); if(hd2<=sze2) minn=a[que2[hd2]]; minn=min(minn,a[pos]); if(maxx-minn>k) break; while(hd1<=sze1&&a[que1[sze1]]<a[pos]) sze1--; que1[++sze1]=pos; while(hd2<=sze2&&a[que2[sze2]]>a[pos]) sze2--; que2[++sze2]=pos; pos++; } ans=max(ans,pos-i); } printf("%lld\n",ans); return 0; }
C. 回文
一开始以为是 $\operatorname{manacher}$ 后来发现算法瓶颈不在于这里
考虑 $\operatorname{DP}$ ,可以首先设 $dp[i][j]$ 为 $i\to j$ 是否是回文串进行一个预处理
预处理可以用 $\operatorname{hash}$ 做到 $\Theta(n^2)$
然后更改 $dp$ 数组的意义,令 $dp[i][j]$ 维护 $(1,1)$ 到 $(i,j)$ 区间内的回文个数,便可以做到 $\Theta(1)$ 查询
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<cstdio> #include<cstring> #include<algorithm> #include<string> #define int long long #define WR WinterRain using namespace std; const int WR=1001000,INF=2147483647; const int base=233; char str[WR]; int len; int dp[5020][5020]; struct Hash{ unsigned int hash[WR],bse[WR]; void init(){ bse[0]=hash[0]=1; for(int i=1;i<=WR;i++){ bse[i]=bse[i-1]*base; } } void get_hash(char str[]){ for(int i=1;i<=strlen(str+1);i++){ hash[i]=hash[i-1]*base+str[i]-'a'; } } unsigned int query(int l,int r){ return hash[r]-hash[l-1]*bse[r-l+1]; } }forw,bckw; int read(){ int s=0,w=1; char ch=getchar(); while(ch>'9'||ch<'0'){ if(ch=='-') w=-1; ch=getchar(); } while(ch>='0'&&ch<='9'){ s=(s<<3)+(s<<1)+ch-48; ch=getchar(); } return s*w; } signed main(){ scanf("%s",str+1); len=strlen(str+1); forw.init(),bckw.init(); forw.get_hash(str); reverse(str+1,str+1+len); bckw.get_hash(str); for(int i=1;i<=len;i++){ for(int j=i;j<=len;j++){ if(forw.query(i,j)==bckw.query(len-j+1,len-i+1)) dp[i][j]=1; else dp[i][j]=0; //printf("%lld ",dp[i][j]); } //printf("\n"); } for(int i=1;i<=len;i++){ for(int j=1;j<=len;j++){ dp[i][j]=dp[i][j]+dp[i][j-1]+dp[i-1][j]-dp[i-1][j-1]; } } int q=read(); while(q--){ int l=read(),r=read(); printf("%lld\n",dp[r][r]-dp[r][l-1]-dp[l-1][r]+dp[l-1][l-1]); } return 0; }
D. 基因进化
本文来自博客园,作者:冬天丶的雨,转载请注明原文链接:https://www.cnblogs.com/WintersRain/p/16519006.html
为了一切不改变的理想,为了改变不理想的一切