OIFC NOI2023省队集训

news/2025/10/21 9:45:06/文章来源:https://www.cnblogs.com/SmpaelFx/p/19152847

T1 绕口令 twister

字符串


题意

给定环形字符串 \(s\),对 \(k\)\(1\)\(n\),判断是否能删去一个长 \(k\) 子段,使得剩余部分无相邻相同字符。


考虑已有的相邻相同字符,必须截断。再删去一个子段可能导致剩余部分的两端变为相同,则问题可转为子段中是否存在距离为 \(k\) 的字符不同的位置。

做法1

考虑暴力做法,枚举 \(i\)\(l\)\(r\),再枚举 \(j\)\(i+1\)\(r\),如果 \(s_{j-1}=s_j\) 直接 break。考虑优化,发现只有 \(s_j=s_l\)\(j-l\) 需要继续考虑 \((l+1,j+1)\),如果仍相等,会继续判断 \((l+2,j+2)\),一直进行下去知道不相等或碰到边界。发现碰到边界当且仅当 \(lcp(s_l,s_j)=r-j+1\) 用扩展 KMP 即可判断。

做法2

考虑不存在距离为 \(k\) 的字符不同的位置相当于 \(s[l:r-k]=s[l+k:r]\),用字符串哈希/KMP即可判断。


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
typedef pair<int,ll> pil;
typedef pair<ll,int> pli;
typedef pair<ll,ll> pll;
template<typename T>
void chkmin(T &x,const T &y){x=min(x,y);}
template<typename T>
void chkmax(T &x,const T &y){x=max(x,y);}
const int inf=0x3f3f3f3f;
const ll infll=0x3f3f3f3f3f3f3f3f;
const int MOD=998244353;
void add(int &x,int y){x+=y;if(x>=MOD) x-=MOD;
}
int qpow(int a,ll b){int mul=1;while(b){if(b&1) mul=(ll)mul*a%MOD;a=(ll)a*a%MOD;b>>=1;}return mul;
}
const int N=2000005;
int n,ans[N],vis[N],len[N];
string s;
void calc(int l,int r){int box=l;len[l]=0;for(int i=0;i<(r-l+1);i++) vis[i]=0;vis[0]=1;for(int i=l+1;i<=r;i++){if(i<box+len[box]) len[i]=min(len[i-box+l],box+len[box]-i);else len[i]=0;while(i+len[i]<=r&&s[l+len[i]]==s[i+len[i]]) len[i]++;if(i+len[i]>box+len[box]) box=i;if(i+len[i]<=r) vis[i-l]=1;}
}
bool solve(int Case){if(!(cin>>s)) return false;cout<<"Case "<<Case<<": ";n=s.size();s=" "+s+s;for(int i=0;i<n;i++) ans[i]=0;ans[n-1]=1;vector<int> vec;for(int i=1;i<=n;i++) if(s[i]==s[i+1]) vec.push_back(i);if(vec.empty()){calc(1,n);ans[0]=1;for(int i=0;i<n;i++){if(i) ans[i-1]|=vis[i];ans[n-i-1]|=vis[i];}for(int i=0;i<n;i++) cout<<ans[i];cout<<'\n';return true;}for(int ind=0;ind<vec.size();ind++){int i=vec[ind],j=vec[(ind+1)%vec.size()];if(j<=i) j+=n;calc(i+1,j);for(int k=0;k<j-i;k++) ans[n-k-1]|=vis[k];}for(int i=0;i<n;i++) cout<<ans[i];cout<<'\n';return true;
}
int main(){#ifndef JZQfreopen("twister.in","r",stdin);freopen("twister.out","w",stdout);#endifios::sync_with_stdio(false);int T=0;while(++T&&solve(T));return 0;
}

T2 图论 graph

图论、网络流、匹配


题意

给定一个有向图,图上的一些边是“重要的”。你的任务是,求出至少需要多少条路径,才能覆盖所有“重要的”边至少一次。

路径可以不是简单路径,亦即可以经过同一个点或者同一条边多次。


做法1

缩强连通分量,把必经边拆成两条边+一个必经点。暴力的做法是,求传递闭包,取出必经点的生成子图求最小连覆盖。考虑最小连覆盖等于点数-拆点二分图最大匹配,传递闭包可以直接放在右部点内部。

具体地,对缩点拆边后的图 \(G=(V,E)\),对 \((u,v)\in E\),在拆点二分图上加入容量为 \(1\)\((u,v')\) 和容量为 \(+\infty\)\((u',v')\);对必经点 \(u\),在拆点二分图上加入容量为 \(+\infty\)\((S,u)\)\((u',T)\)

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
typedef pair<int,ll> pil;
typedef pair<ll,int> pli;
typedef pair<ll,ll> pll;
template<typename T>
void chkmin(T &x,const T &y){x=min(x,y);}
template<typename T>
void chkmax(T &x,const T &y){x=max(x,y);}
const int inf=0x3f3f3f3f;
const ll infll=0x3f3f3f3f3f3f3f3f;
const int MOD=998244353;
void add(int &x,int y){x+=y;if(x>=MOD) x-=MOD;
}
int qpow(int a,ll b){int mul=1;while(b){if(b&1) mul=(ll)mul*a%MOD;a=(ll)a*a%MOD;b>>=1;}return mul;
}
const int N=50005,M=100005;
int n,m,dfn[N],low[N],tot,instack[N],id[N],vis[N+M];
stack<int> st;
vector<int> G[N];
void dfs(int u){dfn[u]=low[u]=++tot,instack[u]=1;st.push(u);for(auto v:G[u]){if(!dfn[v]){dfs(v);chkmin(low[u],low[v]);}else if(instack[v]) chkmin(low[u],dfn[v]);}if(dfn[u]==low[u]){while(st.top()!=u){int v=st.top();st.pop();id[v]=u,instack[v]=0;}st.pop();id[u]=u,instack[u]=0;}
}
namespace Flow{struct Edge{int u,v,c,f;Edge(){}Edge(int u,int v,int c,int f):u(u),v(v),c(c),f(f){}};Edge es[(M*12)+(N<<2)];int s,t,tot,dis[(N+M)<<1],vis[(N+M)<<1],cur[(N+M)<<1];vector<int> G[(N+M)<<1];void addEdge(int u,int v,int c){G[u].push_back(tot);es[tot++]=Edge(u,v,c,0);G[v].push_back(tot);es[tot++]=Edge(v,u,0,0);}bool bfs(){for(int i=s;i<=t;i++) dis[i]=inf,vis[i]=cur[i]=0;queue<int> q;q.push(s),dis[s]=0;while(q.size()){int u=q.front();q.pop();if(vis[u]) continue;vis[u]=1;for(auto eid:G[u]){auto e=es[eid];if(e.f<e.c&&dis[e.v]>dis[u]+1){dis[e.v]=dis[u]+1;q.push(e.v);}}}return dis[t]!=inf;}int dfs(int u,int t,int flow){if(u==t) return flow;int sum=0;for(int &i=cur[u];i<G[u].size();i++){auto &e=es[G[u][i]];if(e.f<e.c&&dis[e.v]==dis[u]+1){int tmp=dfs(e.v,t,min(flow-sum,e.c-e.f));e.f+=tmp,es[G[u][i]^1].f-=tmp;sum+=tmp;}if(sum==flow) break;}return sum;}int calc(){int sum=0;while(bfs()){sum+=dfs(s,t,inf);}return sum;}
}
void solve(){scanf("%d%d",&n,&m);vector<tuple<int,int,int>> es;for(int i=1;i<=m;i++){int u,v,t;scanf("%d%d%d",&u,&v,&t);es.push_back({u,v,t});G[u].push_back(v);}for(int i=1;i<=n;i++) if(!dfn[i]) dfs(i);vector<pii> es2;for(auto [u,v,t]:es){if(t&&id[u]==id[v]) vis[id[u]]=1;else if(t&&id[u]!=id[v]) vis[++n]=1,es2.push_back({id[u],n}),es2.push_back({n,id[v]});else if(id[u]!=id[v]) es2.push_back({id[u],id[v]});}Flow::s=0,Flow::t=(n<<1)+1;int cnt=0;for(int i=1;i<=n;i++) if(vis[i]){Flow::addEdge(0,i,1),Flow::addEdge(n+i,(n<<1)+1,1);cnt++;}for(auto [u,v]:es2) Flow::addEdge(u,n+v,1),Flow::addEdge(n+u,n+v,inf);printf("%d\n",cnt-Flow::calc());
}
int main(){#ifndef JZQfreopen("graph.in","r",stdin);freopen("graph.out","w",stdout);#endifint T=1;while(T--) solve();return 0;
}

做法2

直接跑有源汇上下界最小流,把必经边流量下界设为 \(1\),源点连向每一个点,每一个点连向汇点。

先求有源汇上下界可行流,注意要连一条源点到汇点容量为 \(+\infty\) 的边 \(e\),然后加超级源点、超级汇点。

跑出可行流后,删去附加边,从 \(T\)\(S\) 退流。

答案为 \(e\) 的流量 - 退流流量。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
typedef pair<int,ll> pil;
typedef pair<ll,int> pli;
typedef pair<ll,ll> pll;
template<typename T>
void chkmin(T &x,const T &y){x=min(x,y);}
template<typename T>
void chkmax(T &x,const T &y){x=max(x,y);}
const int inf=0x3f3f3f3f;
const ll infll=0x3f3f3f3f3f3f3f3f;
const int MOD=998244353;
void add(int &x,int y){x+=y;if(x>=MOD) x-=MOD;
}
int qpow(int a,ll b){int mul=1;while(b){if(b&1) mul=(ll)mul*a%MOD;a=(ll)a*a%MOD;b>>=1;}return mul;
}
const int N=50005,M=100005;
int n,m,s[N];
stack<int> st;
vector<int> G[N];
namespace Flow{struct Edge{int u,v,c,f;Edge(){}Edge(int u,int v,int c,int f):u(u),v(v),c(c),f(f){}};Edge es[(M<<1)+(N*6)];int tot,dis[N],vis[N],cur[N];vector<int> G[N];void addEdge(int u,int v,int c){G[u].push_back(tot);es[tot++]=Edge(u,v,c,0);G[v].push_back(tot);es[tot++]=Edge(v,u,0,0);}bool bfs(int s,int t){for(int i=1;i<=n;i++) dis[i]=inf,vis[i]=cur[i]=0;queue<int> q;q.push(s),dis[s]=0;while(q.size()){int u=q.front();q.pop();if(vis[u]) continue;vis[u]=1;for(auto eid:G[u]){auto e=es[eid];if(e.f<e.c&&dis[e.v]>dis[u]+1){dis[e.v]=dis[u]+1;q.push(e.v);}}}return dis[t]!=inf;}int dfs(int u,int t,int flow){if(u==t) return flow;int sum=0;for(int &i=cur[u];i<G[u].size();i++){auto &e=es[G[u][i]];if(e.f<e.c&&dis[e.v]==dis[u]+1){int tmp=dfs(e.v,t,min(flow-sum,e.c-e.f));e.f+=tmp,es[G[u][i]^1].f-=tmp;sum+=tmp;}if(sum==flow) break;}return sum;}int calc(int s,int t){int sum=0;while(bfs(s,t)){sum+=dfs(s,t,inf);}return sum;}
}
void solve(){scanf("%d%d",&n,&m);vector<tuple<int,int,int>> es;for(int i=1;i<=m;i++){int u,v,t;scanf("%d%d%d",&u,&v,&t);Flow::addEdge(u,v,inf);if(t) s[u]--,s[v]++;}int tmp=n;int s0=++n,t0=++n,s1=++n,t1=++n;for(int i=1;i<=tmp;i++) Flow::addEdge(s0,i,inf),Flow::addEdge(i,t0,inf);for(int i=1;i<=tmp;i++){if(s[i]>0) Flow::addEdge(s1,i,s[i]);else if(s[i]<0) Flow::addEdge(i,t1,-s[i]);}Flow::addEdge(t0,s0,inf);Flow::calc(s1,t1);int ans=Flow::es[Flow::tot-2].f;Flow::G[s0].pop_back(),Flow::G[t0].pop_back();printf("%d\n",ans-Flow::calc(t0,s0));
}
int main(){#ifndef JZQfreopen("graph.in","r",stdin);freopen("graph.out","w",stdout);#endifint T=1;while(T--) solve();return 0;
}

T3 配音演员 vocal

构造、图论


题意

做法

有没有可能不会无解?考虑证明,不难想到使用归纳法。

假设 \((n-1)\)-Benes 网络能够接受任意变换,只需决定每一个输入被放到左边还是右边。关注第一个交换器,发现0和1不能被放到相同一侧,进一步,发现第一行每一个交换器的输出都在不同两侧,最后一行每个交换器输入都在不同两侧。设 \(a_i\) 表示 \(i\) 被放到左/右侧,则 \(a_0\neq a_1,a_2\neq a_3,\dots\)\(a_{p_0}\neq a_{p_1},a_{p_2}\neq a_{p_3},\dots\)。这是一个黑白染色问题,直接跑即可。

考虑证明永远存在一个解:每一个点度数恒等于 \(2\),且边可以被黑白染色(第一行连的边不相邻、最后一行连的边不相邻),因此恒存在黑白染色方案。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
typedef pair<int,ll> pil;
typedef pair<ll,int> pli;
typedef pair<ll,ll> pll;
template<typename T>
void chkmin(T &x,const T &y){x=min(x,y);}
template<typename T>
void chkmax(T &x,const T &y){x=max(x,y);}
const int inf=0x3f3f3f3f;
const ll infll=0x3f3f3f3f3f3f3f3f;
const int MOD=998244353;
void add(int &x,int y){x+=y;if(x>=MOD) x-=MOD;
}
int qpow(int a,ll b){int mul=1;while(b){if(b&1) mul=(ll)mul*a%MOD;a=(ll)a*a%MOD;b>>=1;}return mul;
}
const int N=20,M=(1<<13)+5;
int n,p[M],q[M],tmp[M],ans[N<<1][M],vis[M],color[M];
vector<int> G[M];
void shuf(int p[],int l,int r){int n=r-l;for(int i=0;i<n;i++){int j=(i>>1);if(i&1) j|=(n>>1);tmp[j+l]=p[i+l];}for(int i=l;i<r;i++) p[i]=tmp[i];
}
bool dfs(int u,int t){if(vis[u]){if(t==color[u]) return true;return false;}vis[u]=1,color[u]=t;for(auto v:G[u]) if(!dfs(v,t^1)) return false;return true;
}
bool check(int l,int r){for(int i=l;i<r;i++) vis[p[i]]=color[p[i]]=0;for(int i=l;i<r;i++){if(vis[p[i]]) continue;if(!dfs(p[i],0)) return false;}return true;
}
bool solve(int l,int r,int row1,int row2){if(r-l==2){if(p[l]==q[l]) ans[row1][l>>1]=0;else ans[row1][l>>1]=1;return true;}for(int i=l;i<r;i++) G[p[i]].clear();for(int i=l;i<r;i+=2){G[p[i]].push_back(p[i+1]),G[p[i+1]].push_back(p[i]);G[q[i]].push_back(q[i+1]),G[q[i+1]].push_back(q[i]);}if(!check(l,r)) return false;for(int i=l;i<r;i+=2){ans[row1][i>>1]=color[p[i]];if(color[p[i]]) swap(p[i],p[i+1]);}for(int i=l;i<r;i+=2){ans[row2][i>>1]=color[q[i]];if(color[q[i]]) swap(q[i],q[i+1]);}int mid=(l+r)>>1;shuf(p,l,r),shuf(q,l,r);return solve(l,mid,row1+1,row2-1)&&solve(mid,r,row1+1,row2-1);
}
bool solve(bool flag){scanf("%d",&n);if(!n) return false;if(flag) printf("\n");for(int i=0;i<(1<<n);i++) scanf("%d",&q[i]);for(int i=0;i<(1<<n);i++) p[i]=i;if(!solve(0,1<<n,0,(n-1)<<1)){printf("impossible\n");return false;}for(int i=0;i<=((n-1)<<1);i++){for(int j=0;j<(1<<(n-1));j++) printf("%d",ans[i][j]);printf("\n");}return true;
}
int main(){#ifndef JZQfreopen("vocal.in","r",stdin);freopen("vocal.out","w",stdout);#endifbool flag=false;while(solve(flag)) flag=true;return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/941976.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

KingbaseES 启动失败故障排查

KingbaseES 启动失败故障排查KingbaseES 作为国产数据库的主流产品,在日常运维中难免遇到启动失败的问题。这类故障多与配置参数、系统资源或端口冲突相关,核心排查思路是 “日志定位问题 + 配置 / 系统匹配验证”。…

大数据Spark(六十四):Spark算子介绍 - 详解

大数据Spark(六十四):Spark算子介绍 - 详解pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", &q…

2025年10月手操器公司推荐:对比评测榜揭示工业诊断选型要点

一、引言 在流程工业迈向智能化运维的当下,手操器已不仅是现场调校的辅助工具,更是资产完整性管理的数据入口。对于需要采购、升级或替换手操器的仪表工程师、设备经理以及项目承包商而言,核心诉求集中在三点:一是…

SqlServer 事务复制(transaction replication)的复制位点信息

SqlServer 事务复制(transaction replication)的复制位点信息在逻辑复制中,正如MySQL的show slave status,或者postgresql的逻辑复制pg_stat_replication的sent_lsn,来观察复制进度的坐标位点,其复制进度坐标位置…

2025年10月儿童面霜品牌推荐:五强榜单对比评测与选购指南

一、引言 秋末冬初,气温骤降、湿度骤降,0到12岁儿童角质层厚度仅为成人三分之二,经皮失水速度却高出近三成,皴裂、干痒、苹果脸集中爆发。对于每天要为孩子擦脸、又要控制家庭洗护预算的家长而言,如何在“安全、有…

机器人技术领域多元人才培养计划解析

本文介绍了某机构机器人部门举办的"第一天"奖学金项目,该项目旨在支持多元背景技术人才攻读硕士学位,涵盖机器人技术、人工智能等前沿领域研究,并提供实习机会与专业指导,推动技术创新与行业多样性发展。…

20251018NOIP模拟赛

题目大意: 给你一个长度为 \(2 \times n\) 的由 \(\text{(}\) 和 \(\text{)}\) 构成的串,再给你 \(n\) 个二元组 \(a < b\),保证所有的 \(a\) 与 \(b\) 构成了一个长度为 \(2 \times n\) 的排列。 问能否选出一个…

实战案例:职行力如何利用纷享销客CRM实现人效管理数字化突围?

当数字化服务商自身需要数字化转型,会碰撞出怎样的火花?国内领先的人效运营管理平台职行力,服务建发集团、紫金矿业等世界500强企业,为安踏、七匹狼等头部企业人效提升提供解决方案,却选择与纷享销客携手——仅用…

吐槽下特斯拉汽车

吐槽下特斯拉汽车吐槽下特斯拉汽车 1、他的刹车系统可靠性不足,真的有问题。有很多出事故的案例。 2、单踏板模式与常规操作惯例不同,需要用户改变驾驶习惯,紧急情况下容易把油门当刹车误操作引起事故。 3、隐藏式电…

2025年10月素材平台对比评测榜:高品图像领衔五强深度解析

一、引言 在内容生产节奏以小时计的当下,创业者、品牌方、新媒体编辑、教育出版机构对“正版、高清、可商用”素材的需求已从“锦上添花”变成“刚需”。选错平台,轻则授权链路断裂导致下架,重则高额索赔;选对平台…

示波器接地环路与电磁脉冲干扰:原理、影响及应对策略

在电子测量领域,示波器是捕获电信号波形的关键工具,其测量精度直接影响实验分析和故障排查的可靠性。然而,接地环路过大是导致示波器测量误差和引入干扰的常见问题,而其是否会接收空气中的电磁脉冲(EMP),需要从…

2025 年国内传感器厂家最新推荐排行榜:聚焦磁致伸缩 / 防爆 / 防水 / 线性 / 液位等多类型传感器,精选优质企业

引言 当前传感器行业飞速发展,市场中品牌与产品数量激增,却存在技术水平参差不齐、质量稳定性差异大的问题。企业和采购者在挑选磁致伸缩、防爆、防水等各类传感器时,常因缺乏权威参考依据,难以精准匹配自身需求,…

Palantir实体工程实践

Palantir实体工程实践Naive RAG,是试图让AI在没有地图的情况下,靠嗅觉找到宝藏。Complex Agent,是试图训练一个没有地图的AI,学会使用各种交通工具。而真正的出路,是Ontology RAG。它的核心,不是让AI更“能干”,…

施普林格论文集:发展中国家城市废物流资源化利用与回收洞察

施普林格论文集:发展中国家城市废物流资源化利用与回收洞察 Title: Insight into the Resource Utilization and Recovery of Urban Waste Streams in Developing Countries 论文集系列:Springer Environmental Scie…

2025 年钢结构厂家最新推荐:优质品牌权威榜单发布,助力客户精准选择可靠合作伙伴

引言 当前钢结构临建设施行业发展面临诸多困境,部分企业为逐短期利益,陷入恶性竞争,以次充好降低成本,致使产品质量参差不齐,既威胁建筑项目安全稳定,又损害行业信誉。同时,临建设施应用场景持续拓展,覆盖建筑…

打印机已发送,但是不打印?一份全面的故障排除指南!

打印机已发送,但是不打印?一篇文章教你如何快速排查! 明明电脑显示 “打印任务已发送”,打印机却纹丝不动 —— 这种糟心场景,相信很多人都遇到过。 打印机不打印的原因五花八门,从简单的连接松动到复杂的驱动故…

2025 年雕塑源头厂家最新推荐排行榜:聚焦婚庆泡沫 / 玻璃钢 / 城市地标不锈钢等多品类,精选优质企业

引言 在当下雕塑行业,客户在选择合作厂家时常常面临诸多困扰:部分厂家存在中间商加价导致成本过高,难以提供高性价比产品;一些企业定制能力有限,无法满足从中小型道具到大型艺术工程的多样化需求,尤其在材质适配…

SOAR技术与高效网络安全运营 - 教程

SOAR技术与高效网络安全运营 - 教程pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco…

清单

.cn-date-taskboard { margin: 30px auto; padding: 0 15px; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", "Microsoft YaHei", sans-serif } .cn-tas…

2025 年国内润滑脂厂家最新推荐排行榜:道达尔 / 工业 / 合成 / 高温 / 轴承润滑脂优选企业详析

引言 当前工业领域对润滑脂的需求愈发多元化,从普通机械润滑到极端工况下的专用润滑,市场对产品品质、适配性及服务的要求不断提升。但市场上品牌繁杂,部分产品存在参数虚标、适配性差等问题,导致设备故障频发;同…