2025省选模拟1
2025省选模拟1
题目来源: 2024省选联测1
HZTG5808. interval
-
考虑按照左端点升序排序后反悔贪心。
-
分别维护已经匹配的区间对和未被匹配的区间,若当前区间
可以和前面剩余的未被匹配的区间匹配则直接匹配;否则尝试找到一对已经匹配的区间 ,若 的右端点比 的右端点靠左则替换成 进行匹配,可以证明将 换成 扩大了 能匹配的区间(如果不换就是 的匹配区间),一定不劣。 -
优先队列按照右端点升序排序即可。
点击查看代码
pair<int,int>a[500010]; priority_queue<int,vector<int>,greater<int> >used,wait; int main() { #define Isaac #ifdef Isaac freopen("interval.in","r",stdin); freopen("interval.out","w",stdout); #endif int n,ans=0,i; scanf("%d",&n); for(i=1;i<=n;i++) { scanf("%d%d",&a[i].first,&a[i].second); } sort(a+1,a+1+n); for(i=1;i<=n;i++) { if(wait.empty()==0&&wait.top()<a[i].first) { ans++; used.push(a[i].second); wait.pop(); } else { if(used.empty()==0&&used.top()<a[i].second) { wait.push(used.top()); used.pop(); used.push(a[i].second); } else { wait.push(a[i].second); } } } printf("%d\n",ans); return 0; }
-
输出方案时只需要记录下来源后倒着给予编号即可。
点击查看代码
struct node { int l,r,id; }a[500010]; int col[500010]; priority_queue<pair<int,int>,vector<pair<int,int> >,greater<pair<int,int> > >used,wait; bool cmp(node a,node b) { return (a.l==b.l)?(a.r<b.r):(a.l<b.l); } int main() { // #define Isaac #ifdef Isaac freopen("interval.in","r",stdin); freopen("interval.out","w",stdout); #endif int n,m,i; scanf("%d%d",&n,&m); for(i=1;i<=n;i++) { scanf("%d%d",&a[i].l,&a[i].r); a[i].id=i; } sort(a+1,a+1+n,cmp); for(i=1;i<=n;i++) { if(wait.empty()==0&&wait.top().first<a[i].l) { col[wait.top().second]=col[a[i].id]=m; m--; used.push(make_pair(a[i].r,a[i].id)); wait.pop(); if(m==0) { break; } } else { if(used.empty()==0&&used.top().first<a[i].r) { wait.push(used.top()); col[a[i].id]=col[used.top().second]; col[used.top().second]=0; used.pop(); used.push(make_pair(a[i].r,a[i].id)); } else { wait.push(make_pair(a[i].r,a[i].id)); } } } for(i=1;i<=n;i++) { if(col[i]==0&&m>=1) { col[i]=m; m--; } printf("%d ",col[i]); } return 0; }
HZTG5809. apers
-
考虑扩展
时最小割的做法。 -
将一个点拆成入点
和出点 ,中间用容量为 的边相连。 -
对经过地雷数进行分层,相邻两层从
向 连一条容量为 的边表示在 放置了地雷(割掉了 )。 -
注意当图不连通时需要输出
。点击查看代码
const ll inf=0x3f3f3f3f3f3f3f3f; ll a[210],id[2][10][210],tot=0; vector<ll>ans; struct MinCut { struct node { ll nxt,to,cap,flow; }e[16010]; ll head[3010],dis[3010],vis[3010],cur[3010],cnt=1; void add(ll u,ll v,ll w) { cnt++; e[cnt]=(node){head[u],v,w,0}; head[u]=cnt; cnt++; e[cnt]=(node){head[v],u,0,0}; head[v]=cnt; } bool bfs(ll s,ll t) { memset(vis,0,sizeof(vis)); queue<ll>q; dis[s]=1; cur[s]=head[s]; q.push(s); vis[s]=1; while(q.empty()==0) { ll x=q.front(); q.pop(); for(ll i=head[x];i!=0;i=e[i].nxt) { if(vis[e[i].to]==0&&e[i].cap>e[i].flow) { dis[e[i].to]=dis[x]+1; cur[e[i].to]=head[e[i].to]; q.push(e[i].to); vis[e[i].to]=1; if(e[i].to==t) return true; } } } return false; } ll dfs(ll x,ll t,ll flow) { if(x==t) return flow; ll sum=0,tmp; for(ll i=cur[x];i!=0&&sum<flow;i=e[i].nxt) { cur[x]=i; if(dis[e[i].to]==dis[x]+1&&e[i].cap>e[i].flow) { tmp=dfs(e[i].to,t,min(e[i].cap-e[i].flow,flow-sum)); if(tmp==0) dis[e[i].to]=0; sum+=tmp; e[i].flow+=tmp; e[i^1].flow-=tmp; } } return sum; } ll Dinic(ll s,ll t) { ll flow=0; while(bfs(s,t)==true) flow+=dfs(s,t,inf); return flow; } }C,D; int main() { #define Isaac #ifdef Isaac freopen("apers.in","r",stdin); freopen("apers.out","w",stdout); #endif ll n,m,k,u,v,s,t,i,j; cin>>n>>m>>k>>s>>t; for(i=1;i<=k;i++) { for(j=1;j<=n;j++) { tot++; id[0][i][j]=tot; tot++; id[1][i][j]=tot; } } for(i=1;i<=n;i++) { cin>>a[i]; for(j=1;j<=k;j++) { C.add(id[0][j][i],id[1][j][i],a[i]); if(j<=k-1) C.add(id[0][j][i],id[1][j+1][i],inf); } } for(i=1;i<=m;i++) { cin>>u>>v; D.add(u,v,inf); for(j=1;j<=k;j++) C.add(id[1][j][u],id[0][j][v],inf); } if(D.bfs(s,t)==true&&D.dis[t]<k) cout<<-1<<endl; else cout<<C.Dinic(id[0][1][s],id[1][k][t])<<endl; return 0; }
-
输出方案同最小割构造。
点击查看代码
const ll inf=0x3f3f3f3f3f3f3f3f; ll a[210],id[2][10][210],tot=0; vector<ll>ans; struct MinCut { struct node { ll nxt,to,cap,flow; }e[16010]; ll head[3010],dis[3010],vis[3010],cur[3010],cnt=1; void add(ll u,ll v,ll w) { cnt++; e[cnt]=(node){head[u],v,w,0}; head[u]=cnt; cnt++; e[cnt]=(node){head[v],u,0,0}; head[v]=cnt; } bool bfs(ll s,ll t) { memset(vis,0,sizeof(vis)); queue<ll>q; dis[s]=1; cur[s]=head[s]; q.push(s); vis[s]=1; while(q.empty()==0) { ll x=q.front(); q.pop(); for(ll i=head[x];i!=0;i=e[i].nxt) { if(vis[e[i].to]==0&&e[i].cap>e[i].flow) { dis[e[i].to]=dis[x]+1; cur[e[i].to]=head[e[i].to]; q.push(e[i].to); vis[e[i].to]=1; if(e[i].to==t) return true; } } } return false; } ll dfs(ll x,ll t,ll flow) { if(x==t) return flow; ll sum=0,tmp; for(ll i=cur[x];i!=0&&sum<flow;i=e[i].nxt) { cur[x]=i; if(dis[e[i].to]==dis[x]+1&&e[i].cap>e[i].flow) { tmp=dfs(e[i].to,t,min(e[i].cap-e[i].flow,flow-sum)); if(tmp==0) dis[e[i].to]=0; sum+=tmp; e[i].flow+=tmp; e[i^1].flow-=tmp; } } return sum; } ll Dinic(ll s,ll t) { ll flow=0; while(bfs(s,t)==true) flow+=dfs(s,t,inf); return flow; } }C,D; int main() { // #define Isaac #ifdef Isaac freopen("apers.in","r",stdin); freopen("apers.out","w",stdout); #endif ll n,m,k,u,v,s,t,i,j; cin>>n>>m>>k>>s>>t; for(i=1;i<=k;i++) { for(j=1;j<=n;j++) { tot++; id[0][i][j]=tot; tot++; id[1][i][j]=tot; } } for(i=1;i<=n;i++) { cin>>a[i]; for(j=1;j<=k;j++) { C.add(id[0][j][i],id[1][j][i],a[i]); if(j<=k-1) C.add(id[0][j][i],id[1][j+1][i],inf); } } for(i=1;i<=m;i++) { cin>>u>>v; D.add(u,v,inf); for(j=1;j<=k;j++) C.add(id[1][j][u],id[0][j][v],inf); } if(D.bfs(s,t)==true&&D.dis[t]<k) cout<<-1<<endl; else { C.Dinic(id[0][1][s],id[1][k][t]); for(i=1;i<=k;i++) { for(j=1;j<=n;j++) { if(C.vis[id[0][i][j]]==1&&C.vis[id[1][i][j]]==0) ans.push_back(j); } } cout<<ans.size()<<endl; for(i=0;i<ans.size();i++) cout<<ans[i]<<" "; } return 0; }
HZTG5810. circles
-
先按照
升序排序。 -
观察到最终的环一定是左右部点交错出现。在枚举右部点的过程中,每加入一个左部点与此同时与先前的所有右部点进行连边,可以看做左部点将若干个链连接形成了环。
-
设
表示处理到第 个右部点且还需要 个左部点进行连接的环的数量。当新加入一个右部点的时候,可以作为一条单独的链加入先前状态集合,有 ,边界为 。接着添加左端点,类似地,有 。 -
在更新过程中每个环仅会在最大左部点断开位置处进行计算,但每个环在两个方向上均会对答案产生一次贡献;且每条边产生了一次贡献但不应在最终的答案中,故
即为所求。点击查看代码
const ll p=1000000007; ll a[5010],f[5010]; 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; } int main() { #define Isaac #ifdef Isaac freopen("circles.in","r",stdin); freopen("circles.out","w",stdout); #endif ll n,sum=0,i,j,k; cin>>n; for(i=1;i<=n;i++) { cin>>a[i]; sum=(sum+a[i])%p; } sort(a+1,a+1+n); for(i=j=1;i<=n;i++) { for(k=n;k>=2;k--) { f[k]=(f[k]+(k-1)*f[k-1]%p)%p; } f[1]=(f[1]+1)%p; for(;j<=n&&a[j]==i;j++) { for(k=0;k<=n;k++) { f[k]=(f[k]+(k+1)*f[k+1]%p)%p; } } } cout<<(f[0]-sum+p)%p*qpow(2,p-2,p)%p<<endl; return 0; }
总结
- 整场都在罚坐。
本文来自博客园,作者:hzoi_Shadow,原文链接:https://www.cnblogs.com/The-Shadow-Dragon/p/18637856,未经允许严禁转载。
版权声明:本作品采用 「署名-非商业性使用-相同方式共享 4.0 国际」许可协议(CC BY-NC-SA 4.0) 进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· 写一个简单的SQL生成工具
· Manus的开源复刻OpenManus初探