2025省选模拟14
2025省选模拟14
题目来源: 2025多校冲刺省选模拟赛16
P1022. 世界⼤战
-
部分分
: 预处理 查询。
点击查看代码
ll f[2010][2010],c[2010]; int main() { #define Isaac #ifdef Isaac freopen("worldwar.in","r",stdin); freopen("worldwar.out","w",stdout); #endif ll n,m,q,x,y,i,j; scanf("%lld%lld",&n,&m); for(i=1;i<=m;i++) scanf("%lld",&c[i]); memset(f,0x3f,sizeof(f)); f[1][1]=0; for(i=1;i<=n;i++) { for(j=1;j<=m;j++) { f[i+1][j]=min(f[i+1][j],f[i][j]+c[j]); f[i][j+1]=min(f[i][j+1],f[i][j]+i*i); } } scanf("%lld",&q); for(i=1;i<=q;i++) { scanf("%lld%lld",&x,&y); printf("%lld\n",f[x][y]); } return 0; }
-
正解
- 考虑从
到 中间经过的若干中转点 的贡献。 - 对于一条竖-横-竖的路径
,其代价为 ,其最小值在 时取到,具体取值因要求为正整数所以取 。 - 设
等于上式。根据调整法,升序枚举 的同时单调栈维护单调递增的 ,预处理前缀和后二分得到答案。 - 特判
时的转移。
点击查看代码
ll c[200010],sum[200010],ans[200010],s[200010],opt[200010],n,top=0; vector<pair<ll,ll> >q[200010]; ll get_opt(ll u,ll v) { return min(max((ll)round((c[v]-c[u])/(v-u)/2.0),1ll),n); } int main() { // #define Isaac #ifdef Isaac freopen("worldwar.in","r",stdin); freopen("worldwar.out","w",stdout); #endif ll m,k,x,y,pos,i,j; scanf("%lld%lld",&n,&m); for(i=1;i<=m;i++) scanf("%lld",&c[i]); scanf("%lld",&k); for(i=1;i<=k;i++) { scanf("%lld%lld",&x,&y); if(y==1) ans[i]=c[1]*(x-1); else q[y].push_back(make_pair(x,i)); } top=s[1]=opt[1]=1; for(i=2;i<=m;i++) { while(top>=2&&opt[top]>=get_opt(s[top],i)) top--; pos=get_opt(s[top],i); top++; s[top]=i; opt[top]=pos; sum[top]=sum[top-1]+(pos-opt[top-1])*c[s[top-1]]+(i-s[top-1])*pos*pos; for(j=0;j<q[i].size();j++) { pos=upper_bound(opt+1,opt+1+top,q[i][j].first)-opt-1; ans[q[i][j].second]=sum[pos]+(q[i][j].first-opt[pos])*c[s[pos]]+(i-s[pos])*q[i][j].first*q[i][j].first; } } for(i=1;i<=k;i++) printf("%lld\n",ans[i]); return 0; }
- 考虑从
P1023. 跳⽔
-
部分分
:枚举全排列。 :从 每次步长为 往下跳链直至 的父亲, 以下的部分则步长为 地跳,特判链底。 :输出 。
因数据过水,代码实测可以通过
中完全二叉树的部分分。点击查看代码
struct node { int nxt,to; }e[4000010]; int head[2000010],du[2000010],f[2000010],fa[2000010],siz[2000010],dep[2000010],son[2000010],top[2000010],a[2000010],cnt=0; void add(int u,int v) { cnt++; e[cnt]=(node){head[u],v}; head[u]=cnt; } void dfs1(int x,int father) { siz[x]=1; fa[x]=father; dep[x]=dep[father]+1; f[dep[x]]=x; for(int i=head[x];i!=0;i=e[i].nxt) { if(e[i].to!=father) { dfs1(e[i].to,x); siz[x]+=siz[e[i].to]; son[x]=(siz[e[i].to]>siz[son[x]])?e[i].to:son[x]; } } } void dfs2(int x,int id) { top[x]=id; if(son[x]!=0) { dfs2(son[x],id); for(int i=head[x];i!=0;i=e[i].nxt) if(e[i].to!=fa[x]&&e[i].to!=son[x]) dfs2(e[i].to,e[i].to); } } int lca(int u,int v) { while(top[u]!=top[v]) { if(dep[top[u]]>dep[top[v]]) u=fa[top[u]]; else v=fa[top[v]]; } return dep[u]<dep[v]?u:v; } int get_dis(int x,int y) { return dep[x]+dep[y]-2*dep[lca(x,y)]; } int main() { #define Isaac #ifdef Isaac freopen("jump.in","r",stdin); freopen("jump.out","w",stdout); #endif int n,u,v,flag=1,sum=0,i; scanf("%d",&n); for(i=1;i<=n-1;i++) { scanf("%d%d",&u,&v); du[u]++; du[v]++; add(u,v); add(v,u); } dfs1(1,0); dfs2(1,1); if(n<=12||du[1]==n-1) { for(i=1;i<=n;i++) a[i]=i; do { flag=1; for(i=2;i<=n&&flag==1;i++) flag&=(get_dis(a[i-1],a[i])<=2); if(flag==1) { for(i=1;i<=n;i++) printf("%d\n",a[i]); return 0; } }while(next_permutation(a+2,a+n)); printf("quake!\n"); } else { sum=0; flag=1; for(i=1;i<=n;i++) { sum+=(du[i]==1); flag&=(du[i]<=2); } if(sum==2&&flag==1) { for(i=1;i<=dep[n]-1;i++) printf("%d\n",f[i]); for(i=dep[n]+1;i<=n;i+=2) printf("%d\n",f[i]); if(i==n+1) printf("%d\n",f[n]); for(i=n-2;i>=dep[n];i-=2) printf("%d\n",f[i]); } else printf("quake!\n"); } return 0; }
-
正解
- 考虑将
这条根链上的点提出来单独考虑。划分成的若干个部分相互独立。 - 设
分别表示能否 进 出/ 进 的儿子出/ 的儿子进 的儿子出/ 的儿子进 出。特别地,当儿子中只有一个非叶子节点时,令 。 进 出,要求 必须是叶子节点。 进 的儿子出,要求先到达 ,然后到达儿子中的非叶子节点(如果有则必须只能有一个),最后跳到叶子节点。 的儿子进 的儿子出,在判掉必须有两个非叶子节点后,要求先到达第一个非叶子节点,然后到达 ,接着到达第二个非叶子节点,最后跳到叶子节点。 的儿子进 出,要求先到达儿子中的叶子节点,再到达非叶子节点,最后跳到 。
和 本质相同,只是构造方案时搜索顺序的差别,故可以合并成一种情况。- 设
分别表示 的子树遍历完后能否停在 / 的儿子。- 从
出要求 能出且 能出或 的其他儿子能出且 进 出。 能出且 进 出,从 跳到 这个叶子节点。 能出且 的儿子进 出,从 跳到 能进的儿子,再跳到 。 的儿子能出要求必须 进 出,否则就跳不出来了。
的儿子出要求 能出且 的儿子能出或 的其他儿子能出且 进 的儿子出。 能出且 进 的儿子出,从 跳到 ,再跳到能出的儿子。 能出且 的儿子进 的儿子出,从 跳到 能进的儿子,再跳到 ,再跳到另一个能出的儿子。 的儿子能出且 进 的儿子出,从 的儿子跳到 ,再跳到能出的儿子。
- 从
点击查看代码
struct node { int nxt,to; }e[4000010]; int head[2000010],f[3][2000010],g[2][2000010],vis[2000010],n,cnt=0; vector<int>s,d; void add(int u,int v) { cnt++; e[cnt]=(node){head[u],v}; head[u]=cnt; } void dfs(int x,int fa) { s.push_back(x); if(x==n) d=s; for(int i=head[x];i!=0;i=e[i].nxt) if(e[i].to!=fa) dfs(e[i].to,x); s.pop_back(); } void dp(int x,int fa) { int son=0,sum=0; f[0][x]=f[1][x]=f[2][x]=1; for(int i=head[x];i!=0;i=e[i].nxt) { if(e[i].to!=fa&&vis[e[i].to]==0) { son++; dp(e[i].to,x); sum+=(f[0][e[i].to]==0&&f[1][e[i].to]==1); f[1][x]&=(f[0][e[i].to]|f[1][e[i].to]); f[2][x]&=(f[0][e[i].to]|f[1][e[i].to]); } } f[1][x]&=(sum<=1); f[2][x]&=(sum<=2); if(son==0) f[1][x]=f[2][x]=0; else f[0][x]=0; } void print_f(int x,int op,int fa) { if(op==0) printf("%d\n",x); if(op==1) { printf("%d\n",x); for(int i=head[x];i!=0;i=e[i].nxt) if(e[i].to!=fa&&vis[e[i].to]==0&&f[0][e[i].to]==0) print_f(e[i].to,3,x); for(int i=head[x];i!=0;i=e[i].nxt) if(e[i].to!=fa&&vis[e[i].to]==0&&f[0][e[i].to]==1) print_f(e[i].to,0,x); } if(op==2) { int sum=0; for(int i=head[x];i!=0;i=e[i].nxt) if(e[i].to!=fa&&vis[e[i].to]==0&&f[0][e[i].to]==0) sum++; if(sum==1) print_f(x,1,fa); else { for(int i=head[x];i!=0;i=e[i].nxt) { if(e[i].to!=fa&&vis[e[i].to]==0&&f[0][e[i].to]==0) { if(sum==2) { print_f(e[i].to,1,x); printf("%d\n",x); sum++; } else print_f(e[i].to,3,x); } } for(int i=head[x];i!=0;i=e[i].nxt) if(e[i].to!=fa&&vis[e[i].to]==0&&f[0][e[i].to]==1) print_f(e[i].to,0,x); } } if(op==3) { for(int i=head[x];i!=0;i=e[i].nxt) if(e[i].to!=fa&&vis[e[i].to]==0&&f[0][e[i].to]==1) print_f(e[i].to,0,x); for(int i=head[x];i!=0;i=e[i].nxt) if(e[i].to!=fa&&vis[e[i].to]==0&&f[0][e[i].to]==0) print_f(e[i].to,1,x); printf("%d\n",x); } } void print_g(int x,int op) { if(x==0) print_f(d[x],op,0); else { if(op==0) { if(g[0][x-1]==1&&f[0][d[x]]==1) { print_g(x-1,0); print_f(d[x],0,0); } else if(g[0][x-1]==1&&f[1][d[x]]==1) { print_g(x-1,0); print_f(d[x],3,0); } else { print_g(x-1,1); print_f(d[x],0,0); } } else { if(g[0][x-1]==1&&f[1][d[x]]==1) { print_g(x-1,0); print_f(d[x],1,0); } else if(g[0][x-1]==1&&f[2][d[x]]==1) { print_g(x-1,0); print_f(d[x],2,0); } else { print_g(x-1,1); print_f(d[x],1,0); } } } } int main() { #define Isaac #ifdef Isaac freopen("jump.in","r",stdin); freopen("jump.out","w",stdout); #endif int u,v,i; scanf("%d",&n); for(i=1;i<=n-1;i++) { scanf("%d%d",&u,&v); add(u,v); add(v,u); } dfs(1,0); for(i=0;i<d.size();i++) vis[d[i]]=1; for(i=0;i<d.size();i++) dp(d[i],0); g[0][0]=f[0][1]; g[1][0]=f[1][1]; for(i=1;i<d.size();i++) { g[0][i]=(g[0][i-1]&(f[0][d[i]]|f[1][d[i]]))|(g[1][i-1]&f[0][d[i]]); g[1][i]=(g[0][i-1]&(f[1][d[i]]|f[2][d[i]]))|(g[1][i-1]&f[1][d[i]]); } if(g[0][d.size()-1]==1) print_g(d.size()-1,0); else printf("quake!\n"); return 0; }
- 考虑将
P1024. 蛤蟆的近亲
-
先让
和 取 缩小值域。 -
部分分
: 预处理 查询。
点击查看代码
int a[510],mex[510][510],w[510][510]; uint s[510][510]; bitset<100210>vis,f; int main() { #define Isaac #ifdef Isaac freopen("frog.in","r",stdin); freopen("frog.out","w",stdout); #endif int n,m,i,j,k; uint l,r,ans=0; scanf("%d%d",&n,&m); for(i=1;i<=n;i++) { scanf("%d",&a[i]); if(a[i]>=100010) a[i]=100010; } for(i=1;i<=n;i++) { vis.set(); for(j=i;j<=n;j++) { vis[a[j]]=0; mex[i][j]=vis._Find_first(); } } for(i=1;i<=n;i++) { f.reset(); for(j=i;j<=n;j++) { for(k=i;k<=j;k++) f[mex[k][j]]=1; w[i][j]=f.count(); } } for(i=n;i>=1;i--) { for(j=1;j<=n;j++) s[i][j]=s[i+1][j]+s[i][j-1]-s[i+1][j-1]+w[i][j]; } for(i=1;i<=m;i++) { scanf("%d%d",&l,&r); l=(l^ans)%n+1; r=(r^ans)%n+1; if(l>r) swap(l,r); ans=s[l][r]; printf("%u\n",ans); } return 0; }
-
正解
- 建议先去温习 2024初三集训模拟测试3 T4 计蒜客 T3729 MEX 中 @APJifengc 写的题解。
总结
的部分分想简单了,以为只会存在两种走的方式。- 为图方便把链底的特判和往下跳的过程合并在了一起
i=min(i+2,n)
然后忘退出了,挂了 。 - 胡出来一个拆成入点和出点后跑路径匹配的有负圈的费用流(但全程流量为
)做法,没时间再写了。
- 为图方便把链底的特判和往下跳的过程合并在了一起
本文来自博客园,作者:hzoi_Shadow,原文链接:https://www.cnblogs.com/The-Shadow-Dragon/p/18732880,未经允许严禁转载。
版权声明:本作品采用 「署名-非商业性使用-相同方式共享 4.0 国际」许可协议(CC BY-NC-SA 4.0) 进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具