多校A层冲刺NOIP2024模拟赛12
1.2024 CSP-S 游记2.高一上十月上旬日记3.冲刺CSP联训模拟24.多校A层冲刺NOIP2024模拟赛02 & csp-s模拟95.多校A层冲刺NOIP2024模拟赛036.csp-s模拟107.多校A层冲刺NOIP2024模拟赛048.高一上十月中旬日记9.多校A层冲刺NOIP2024模拟赛0510.多校A层冲刺NOIP2024模拟赛0611.Panasonic Programming Contest 2024(AtCoder Beginner Contest 375)12.csp-s模拟1113.多校A层冲刺NOIP2024模拟赛0714.多校A层冲刺NOIP2024模拟赛0815.csp-s模拟1216.【LGR-203-Div.4】洛谷入门赛 #2817.多校A层冲刺NOIP2024模拟赛0918.信友队2024CSP-S第二轮(复赛)模拟赛19.AtCoder Beginner Contest 37620.高一上十月下旬日记21.多校A层冲刺NOIP2024模拟赛1022.多校A层冲刺NOIP2024模拟赛11
23.多校A层冲刺NOIP2024模拟赛12
24.2024 CSP-S 第二轮多校A层冲刺NOIP2024模拟赛12
A. Alice 和璀璨花
-
部分分
- 测试点
:设 表示前 位中生长趋势子序列长度为 时的末尾最小元素,然后进行暴力转移。 - 测试点
:观察到至多选择 个数。 - 测试点
:做法同最长上升子序列。
点击查看代码
ll a[1000010],b[1000010],d[1000010],f[1000010],g[1000010]; struct BIT { ll c[1000010]; ll lowbit(ll x) { return (x&(-x)); } void update(ll n,ll x,ll val) { for(ll i=x;i<=n;i+=lowbit(i)) { c[i]=max(c[i],val); } } ll getsum(ll x) { ll ans=0; for(ll i=x;i>=1;i-=lowbit(i)) { ans=max(ans,c[i]); } return ans; } }T; int main() { freopen("alice.in","r",stdin); freopen("alice.out","w",stdout); ll n,ans=0,flag=1,i,j; scanf("%lld",&n); for(i=1;i<=n;i++) { scanf("%lld",&a[i]); d[i]=a[i]; } for(i=1;i<=n;i++) { scanf("%lld",&b[i]); flag&=(b[i]==1); } if(flag==1) { sort(d+1,d+1+n); d[0]=unique(d+1,d+1+n)-(d+1); for(i=1;i<=n;i++) { a[i]=lower_bound(d+1,d+1+d[0],a[i])-d; g[i]=T.getsum(a[i]-1)+1; T.update(d[0],a[i],g[i]); ans=max(ans,g[i]); } } else { flag=1; for(i=1;i<=n;i++) { flag&=(b[i]>1); } memset(f,0x3f,sizeof(f)); f[0]=0; if(flag==1) { for(i=1;i<=n;i++) { for(j=min(i,40ll);j>=1;j--) { if(f[j-1]!=0x3f3f3f3f3f3f3f3f&&f[j-1]*b[j-1]<a[i]) { f[j]=min(f[j],a[i]); } } } for(i=min(n,40ll);i>=1;i--) { if(f[i]!=0x3f3f3f3f3f3f3f3f) { ans=i; break; } } } else { for(i=1;i<=n;i++) { for(j=i;j>=1;j--) { if(f[j-1]!=0x3f3f3f3f3f3f3f3f&&f[j-1]*b[j-1]<a[i]) { f[j]=min(f[j],a[i]); } } } for(i=n;i>=1;i--) { if(f[i]!=0x3f3f3f3f3f3f3f3f) { ans=i; break; } } } } printf("%lld\n",ans); fclose(stdin); fclose(stdout); return 0; }
- 测试点
-
正解
- 在
一定时,有 随 单调递增。 - 不妨把
分为两部分使得前半部分的数 ,后半部分的数 ,并设前半部分在 处结尾。 - 当
时,转移是没有意义的;当 时才可能进行转移。 是比较显然的。 ,由 的分割性有 ,自然不会再进行转移。
点击查看代码
ll a[1000010],b[1000010],f[1000010]; int main() { freopen("alice.in","r",stdin); freopen("alice.out","w",stdout); ll n,ans=0,i,j; scanf("%lld",&n); for(i=1;i<=n;i++) { scanf("%lld",&a[i]); } for(i=1;i<=n;i++) { scanf("%lld",&b[i]); } memset(f,0x3f,sizeof(f)); f[0]=0; for(i=1;i<=n;i++) { j=lower_bound(f+1,f+1+n,a[i])-f; if(f[j-1]*b[j-1]<a[i]) { f[j]=min(f[j],a[i]); } } for(i=n;i>=1;i--) { if(f[i]!=0x3f3f3f3f3f3f3f3f) { ans=i; break; } } printf("%lld\n",ans); fclose(stdin); fclose(stdout); return 0; }
- 在
B. Bob 与幸运日
-
部分分
- 测试点
- 等价于求
的数量. - 同余两边同时加
,得到 。 - 设
,有 ,得到 。 - 将
代入第二个式子,并设 ,移项得到 。 - 为方便书写,用
分别代替 ,可以证明其并不会对答案产生影响。 - 此时有
,而容易得到 的一组特解 ,从而得到 - 由
进一步化简可以得到 ,即 。 枚举合法的 即可。
- 等价于求
- 测试点
- 考虑直接枚举
的值,进一步求出 ,接着手动判断是否有 。 - 而计算
中模 等于一个特定值的数个数是平凡的。 - 时间复杂度为
。
- 考虑直接枚举
- 测试点
- 因为数据点随机,所以不会有
的数据。 - 直接移项得到
,进一步求出 。 - 时间复杂度为
。
- 因为数据点随机,所以不会有
点击查看代码
ll qpow(ll a,ll b,ll p) { ll ans=1; while(b) { if(b&1) { ans=ans*a%p; } b>>=1; a=a*a%p; } return ans; } ll work(ll m,ll d,ll x,ll w) { return (min(m,d)-x)/w+(1<=x&&x<=min(m,d)); } int main() { freopen("bob.in","r",stdin); freopen("bob.out","w",stdout); ll t,m,d,w,a,b,c,e,ans,x,y,i,l,r; scanf("%lld",&t); for(i=1;i<=t;i++) { scanf("%lld%lld%lld%lld%lld",&m,&d,&w,&a,&b); ans=0; a=(a+d)%w; b=(b+d)%w; c=(b-a*d%w+w)%w; e=(d*d-1)%w; if(e==0) { if(min(m,d)<=w) { for(x=1;x<=min(m,d);x++) { if((c+e*x%w)%w==0) { l=ceil(1.0*(x*d+1-a)/w); r=(min(m,d)+x*d-a)/w; ans+=(l<=r)*(r-l+1); } } } else { for(x=0;x<=w-1;x++) { y=(a-x*d%w+w)%w; ans+=((y*d+x)%w==b)*work(m,d,x,w)*work(m,d,y,w); } } } else { x=(w-c)%w*qpow(e,w-2,w)%w; y=(a-x*d%w+w)%w; ans=work(m,d,x,w)*work(m,d,y,w); } printf("%lld\n",ans); } fclose(stdin); fclose(stdout); return 0; }
- 测试点
-
正解
- 考虑
时怎么处理。 - 当
时- 展开得到
,并令 。 - 枚举
的时间复杂度是 ,但枚举 的时间复杂度是 ,直接根号分治即可。
- 展开得到
- 当
时- 展开得到
,并令 。 - 类似地根号分治即可。
- 展开得到
点击查看代码
ll qpow(ll a,ll b,ll p) { ll ans=1; while(b) { if(b&1) { ans=ans*a%p; } b>>=1; a=a*a%p; } return ans; } ll work(ll m,ll d,ll x,ll w) { return (min(m,d)-x)/w+(1<=x&&x<=min(m,d)); } int main() { freopen("bob.in","r",stdin); freopen("bob.out","w",stdout); ll t,m,d,w,a,b,c,e,ans,x,y,s,i,j; scanf("%lld",&t); for(i=1;i<=t;i++) { scanf("%lld%lld%lld%lld%lld",&m,&d,&w,&a,&b); ans=0; a=(a+d)%w; b=(b+d)%w; c=(b-a*d%w+w)%w; e=(d*d-1)%w; if(e==0) { s=sqrt(min(m,d))+1; if(d%w==1) { if(a==b) { if(w<=s) { for(x=0;x<=w-1;x++) { y=(a-x+w)%w; ans+=work(m,d,x,w)*work(m,d,y,w); } } else { for(j=a;j<=2*min(m,d);j+=w) { ans+=(j<=min(m,d))?j-1:2*min(m,d)-j+1; } } } } else { if(a==w-b) { if(w<=s) { for(x=0;x<=w-1;x++) { y=(a+x)%w; ans+=work(m,d,x,w)*work(m,d,y,w); } } else { for(j=a;j<=min(m,d)-1;j+=w) { ans+=min(m,d)-j; } for(j=b;j<=min(m,d)-1;j+=w) { ans+=min(m,d)-j; } } } } } else { x=(w-c)%w*qpow(e,w-2,w)%w; y=(a-x*d%w+w)%w; ans=work(m,d,x,w)*work(m,d,y,w); } printf("%lld\n",ans); } fclose(stdin); fclose(stdout); return 0; }
- 挂一下官方题解的
set
维护做法。-
用
分别代替 ;且 。
-
- 考虑
C. Charlie 的运输网
-
没看出来是二分图。
D. David 与和谐号
-
容易想到的一种翻转方案是,从大到小枚举
,每次将 翻转到 再翻转到 ,故答案上界为 。 -
观察到
,故步数不多,考虑迭代加深。 -
每次翻转只会改变一对相邻数对之间的差,故最终答案一定会大于相邻数对之间差
的数量。 -
需要适当剪枝,时间复杂度为
。点击查看代码
int a[30],flag; bool check(int n) { for(int i=1;i<=n;i++) { if(a[i]!=i) { return false; } } return true; } void dfs(int sum,int cnt,int last,int ans,int n) { if(sum+cnt>ans)//最优性剪枝 { return; } if(check(n)==true) { flag=1; return; } for(int i=n;i>=2;i--) { if(i!=last)//转回来一定不优 { int tmp=cnt-(i!=n&&abs(a[i]-a[i+1])>1)+(i!=n&&abs(a[1]-a[i+1])>1); reverse(a+1,a+1+i); dfs(sum+1,tmp,i,ans,n); reverse(a+1,a+1+i); if(flag==1) { return; } } } } int main() { freopen("david.in","r",stdin); freopen("david.out","w",stdout); int t,n,cnt,ans=0,i,j; cin>>t; for(j=1;j<=t;j++) { cin>>n; cnt=flag=0; for(i=1;i<=n;i++) { cin>>a[i]; } for(i=2;i<=n;i++) { cnt+=(abs(a[i]-a[i-1])>1); } for(ans=0;;ans++) { dfs(0,cnt,0,ans,n); if(flag==1) { cout<<ans<<endl; break; } } } fclose(stdin); fclose(stdout); return 0; }
总结
一开始以为做法和最长上升子序列差不多,遂写了权值树状数组、动态开点线段树优化转移,然后发现假了。在写完 的部分分后去上了趟厕所,回来的时候已经快 了,强逼着自己把测试点 部分分写完了就去推 的式子了。- 貌似最长上升子序列做法也是对的,详见 @ccxswl 的做法,但是需要平衡树维护,没理解为啥对。
推了半天式子才写了个 的做法,结果发现和 一个分。 仅留了半个小时看题,直接摆烂了。
本文来自博客园,作者:hzoi_Shadow,原文链接:https://www.cnblogs.com/The-Shadow-Dragon/p/18499964,未经允许严禁转载。
版权声明:本作品采用 「署名-非商业性使用-相同方式共享 4.0 国际」许可协议(CC BY-NC-SA 4.0) 进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具