CCPC online 2025题解 ( A~H+K)

news/2025/9/22 22:09:38/文章来源:https://www.cnblogs.com/L-fire/p/19102930

没代码的就是队友写的,只提供思路

E

签到题,首先可以算出两人胜利的场次数,答案就是较小的那个*2+1

K

找规律题,打个表可以发现输出 \(n\)\(1\) 即可

A

签到题,枚举每种正方形的边对应的向量,则能构成该种正方形的顶点个数应当构成一个矩形,直接二维差分即可

G

赛事写的根号分治,然而可以根本不用

记下所有数出现的位置,已经出现次数 \(c_i\)

对于一次询问,直接枚举两个数中出现次数较小的数的所有位置,二分另一处即可

复杂度证明应该类似启发式(笔者没证),注意记忆化或特判相等情况就好了

B

这题跟 AGC023F 思路做法一模一样,感觉出题人就是根据这个出的

只要做过这个题的基本都能过(然而我们队没判相等条件,喜提 WA )

首先我们的攻击力是不变的,可以先算出每个怪兽需要打的次数 \(d_i\),设进入 \(u\) 点时我们的防御力为 \(T\) ,则我们经过这个点的扣血量为 \(d_i*(atk_i-Y)= d_i*atk_i-d_i*Y\),前者固定,最大化 \(d_i*Y\) 即可

问题转化为 ,经过点可以给 \(Y\) 加一或给答案增加 \(d_i*Y\) ,问答案最大值

类似那题,我们考虑贪心,每次将最优点向父亲合并,表示进行完父亲以及之前已经向父亲合并的所有节点后再走这个点

如何找最优解,考虑临项交换,设该已经相互合并的点的 \(t_i=1\) 的节点个数为 \(c_u\) , \(d_i\) 之和为 \(r_u\),考虑两个不同的集合 \(u,v\),两种情况分别为

1.\(Y\)\(u\) 贡献的答案 \(+\) \(Y\)\(v\) 贡献的答案 \(+\) \(c_u*r_v\) (先进 \(u\) 后进 \(v\))

2.\(Y\)\(v\) 贡献的答案 \(+\) \(Y\)\(u\) 贡献的答案 \(+\) \(c_v*r_u\) (先进 \(u\) 后进 \(v\))

因此只需比较不同的代价即可知按 \(\frac{c_u}{r_u}\) 排序即可

注意相等情况

点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define int long long
int n,X;
struct edge{int to,nex;
}e[640010];
int head[200100],cnt;
void add(int u,int v)
{e[++cnt]={v,head[u]};head[u]=cnt;
}
int fa[200100];
int dsu[200100];
void dfs(int now,int fath)
{fa[now]=fath;for(int i=head[now];i;i=e[i].nex){int v=e[i].to;if(v==fath) continue;dfs(v,now);}
}
long long ans;
struct node{int x,y,id;bool friend operator<(node a,node b){if(a.x*b.y==a.y*b.x){if(a.x==b.x){return a.id<b.id;}return a.x>b.x;}return a.x*b.y>a.y*b.x;}
}a[640010];
set<node>q;
int find(int x){return x==dsu[x]?x:dsu[x]=find(dsu[x]);}
signed main()
{// freopen("txt.in","r",stdin);// freopen("txt.out","w",stdout);cin>>n>>X;for(int i=1;i<n;i++){int u,v;cin>>u>>v;add(u,v);add(v,u);}dfs(1,0);for(int i=2;i<=n;i++){int t;cin>>t;if(t==1){a[i].x=1;a[i].y=0;}else {int atk,def,hp;cin>>atk>>def>>hp;a[i].x=0;a[i].y=(hp%(X-def)==0?hp/(X-def):hp/(X-def)+1)-1;ans-=a[i].y*atk;}a[i].id=i;q.insert(a[i]);}for(int  i=1;i<=n;i++) dsu[i]=i;while(!q.empty()){node u=*q.begin();q.erase(q.begin());int fai=find(fa[u.id]);if(fai!=1) q.erase(q.find(a[fai]));ans+=a[fai].x*a[u.id].y;a[fai].x+=a[u.id].x;a[fai].y+=a[u.id].y;dsu[u.id]=fai;if(fai!=1) q.insert(a[fai]);}cout<<ans<<endl;return 0;
}

C

据说有巨多种贪心方法,这里讲一下我们队赛事的方法

见完全图最小生成树考虑 Boruvka 算法

只需靠考虑找出 $ (t_v+t_u)\mod k$ 的最小值即可,枚举 \(t_u\) 显然能成为最小值的 \(v\) 只能是 \(\leq 0\)\(\leq k-t_u\) 的最小值取其一,直接用 set 即可

然而我们队非得写线段树二分(感觉赛事我们好傻)

贴个赛事代码(写的又臭又长,没啥参考性)

点击查看代码
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5+10,M=6e6+10,inf=2e9;
int t[N];
int sum[M],ls[M],rs[M];
int idm[M],idmt[M];
int vis[N],ccnt;
set<int>id[N];
int clr[N],clrtot;
struct dsu{int fa[N];inline void init(int n){for(int i=1;i<=n;i++) fa[i]=i;}inline int find(int x){return fa[x]==x?x:fa[x] =find(fa[x]);}
}dsu;
inline void upd(int &p,int l,int r,int pos,int v,int x){if(!p) p = ++ccnt, idm[p]=inf,idmt[p]=-1,ls[p]=rs[p]=sum[p]=0;if(l==r) {sum[p] += v;pos=lower_bound(clr+1,clr+1+clrtot,pos)-clr;if(v==1) id[pos].insert(x);else id[pos].erase(x);if(sum[p]>=1) idm[p]=l,idmt[p]=*id[pos].begin();else idm[p]=inf,idmt[p]=-1;return ;}int mid=(l+r)>>1;if(pos<=mid) upd(ls[p],l,mid,pos,v,x);else upd(rs[p],mid+1,r,pos,v,x);sum[p] = sum[ls[p]] + sum[rs[p]];if(ls[p]&&idm[ls[p]]!=inf) idm[p]=idm[ls[p]],idmt[p]=idmt[ls[p]];else if(rs[p]) idm[p]=idm[rs[p]],idmt[p]=idmt[rs[p]];else idm[p]=inf;if(idm[p]==inf) idmt[p]=-1;return ;
}
inline int findfirst(int p,int l,int r,int bound){if(!p) return -1;if(bound<=l) return idmt[p];if(l==r){if(sum[p]) return *id[lower_bound(clr+1,clr+1+clrtot,l)-clr].begin();else return -1;}int mid=(l+r)>>1;if(bound<=mid){int rl=findfirst(ls[p],l,mid,bound);if(rl!=-1) return rl;}return findfirst(rs[p],mid+1,r,bound);
}
vector<int>vc[N];
int rt;
struct node{int u,v,w;
}e[N];
int cnt;
bool cmp(node x,node y){return x.w<y.w;}
int main(){int T;cin>>T;while(T--){int n,k;cin>>n>>k;for(int i=1;i<=n;i++){cin>>t[i];t[i]%=k;vc[i].push_back(i);clr[++clrtot]=t[i];}sort(clr+1,clr+1+n);clrtot=unique(clr+1,clr+1+n)-clr-1;for(int i=1;i<=n;i++){upd(rt,0,k,t[i],1,i);}int tot=n;long long ans=0;dsu.init(n);while(1){for(int i=1;i<=n;i++) vis[i]=0; if(tot==1) break;cnt=0;dsu.init(n);for(int i=1;i<=tot;i++){for(int j=0;j<vc[i].size();j++){dsu.fa[vc[i][j]]=vc[i][0];upd(rt,0,k,t[vc[i][j]],-1,vc[i][j]);}for(int j=0;j<vc[i].size();j++){int now=t[vc[i][j]];int l=findfirst(rt,0,k,0),r=findfirst(rt,0,k,k-now);if(r==-1) {cnt++;e[cnt]={vc[i][j],l,(now+t[l])%k};}else if(l==-1) {cnt++;e[cnt]={vc[i][j],r,(now+t[r])%k};}else if((now+t[l])%k<=(now+t[r])%k){cnt++;e[cnt]={vc[i][j],l,(now+t[l])%k};}else {cnt++;e[cnt]={vc[i][j],r,(now+t[r])%k};}}for(int j=0;j<vc[i].size();j++){upd(rt,0,k,t[vc[i][j]],1,vc[i][j]);}}sort(e+1,e+1+cnt,cmp);for(int i=1;i<=cnt;i++){int u=dsu.find(e[i].u),v=dsu.find(e[i].v);if(u!=v){ans+=e[i].w;dsu.fa[v]=u;}}for(int i=1;i<=tot;i++){vc[i].clear();}tot=0;for(int i=1;i<=n;i++){if(dsu.fa[i]==i){tot++;vis[i]=tot;vc[tot].push_back(i);}}for(int i=1;i<=n;i++){if(dsu.fa[i]!=i){vc[vis[dsu.find(i)]].push_back(i);}}}cout<<ans<<endl;for(int i=1;i<=clrtot;i++) id[i].clear();clrtot=0;ccnt=rt=0;for(int i=1;i<=n;i++) vc[i].clear();}return 0;
}

D

典题,注意到通配符至多只有 \(10\) 个,考虑先删去通配符,将剩余的每个字符串都跑一边 kmp

枚举子串的左端点 \(l\) ,由于通配符的存在,我们可以尽可能贪心的匹配最后一个通配符之前的所有字符串,再找到最后一个字符串所有符合条件的位置。
注意不要写二分,用双指针即可

点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define ull unsigned long long
#define int long long
const int N=5e5+10;
ull hs[N],pw[N];
inline ull geths(int l,int r){return hs[r] - hs[l-1] * pw[r-l+1];}
char s[N],t[N];
const ull base = 13331;
signed main(){// ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);scanf("%s%s",s+1,t+1);int n = strlen(s+1),m= strlen(t+1);pw[0] = 1;for(int i=1;i<=m;++i){hs[i] = hs[i-1] * base + t[i];pw[i] = pw[i-1] * base;}string lst = "";bool lef = s[1] == '*';bool rig = s[n] == '*';vector<string> sub;for(int i=1;i<=n;++i){if(s[i] == '*'){if(lst != "") sub.emplace_back(lst);lst = "";}else{lst += s[i];}}if(!rig) sub.emplace_back(lst),lst = "";// if(sub.size() == 0) cout<<m*(m+1)/2<<endl,exit(0);vector<vector<int> > lpos(sub.size());vector<int> iter(sub.size());int cnt = 0,ans = 0; for(int it = 0;it<sub.size();++it){string str = sub[it];ull hs_s = 0;for(int j=0;j<str.length();++j) hs_s = hs_s * base + str[j];for(int j=1;j<=m;++j){if(j+str.length()-1>m) break;if(geths(j,j+str.length()-1) == hs_s) lpos[cnt].emplace_back(j);}// for(auto x:lpos[cnt]) cout<<x<<" "; cout<<endl;cnt += 1;}for(int l=1;l<=m;++l){int tar = l;bool flag = true;for(int j=0;j<cnt;++j){while(iter[j] < lpos[j].size() && lpos[j][iter[j]]<tar) iter[j] ++;if(iter[j]>=lpos[j].size()){flag = false;break;}tar = lpos[j][iter[j]] +  sub[j].size();}if(!flag) break;// tar is the minimum Rif(lef == false && lpos[0][iter[0]] != l)  continue;if(rig){if(cnt != 0) ans += m- tar + 2;else ans += m-l+1;}else{ans += lpos[cnt -1].size() - iter[cnt-1];}}printf("%lld\n",ans);return 0;
}

F

典中典博弈论,赛事就是不打表(恼)

首先考虑博弈论部分 ,参考这个题的打表 (CF1704F),你会发现这两个题的 \(SG\)计算过程一模一样,直接套过来就行了

对于初始局面的寻找,可以用 XOR hash 快速定位出所有的子游戏,然后就做完了

H

观察一个性质,每一门课最终只会被一个老师影响

因此我们可以钦定每门课被那个老师影响,即使不合法(比如选了另一个老师的值大于当前钦定的)也不影响答案,因为合法的显然更优

因此考虑 \(dp\) ,记 \(dp_{i,j,S}\) 表示考虑到前 \(i\) 个老师,用了 \(j\) 时间,已经钦定的课程集合为 \(S\) ,直接转移即可

注意转移时不要枚举子集,可以枚举每一门课,从该位为 0 的向 该位为 1 的所有状态转移,就可以做到 \(O(mTn2^n)\)

点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define int long long
int n,m,k,T;
int len[55],t[55];
int l[55][20],to[55][20],clr[55][20],Si[55];
int v[20][10001];
int dp[2][51][16385];
int tmp[16385];
signed main()
{// freopen("txt.in","r",stdin);// freopen("txt.out","w",stdout);cin>>n>>m>>k>>T;int sum=0;for(int i=1;i<=n;i++){for(int j=0;j<=k;j++){cin>>v[i][j];}sum+=v[i][0];}for(int i=1;i<=m;i++){cin>>len[i]>>t[i];for(int j=1;j<=len[i];j++){cin>>l[i][j]>>to[i][j];Si[i]|=(1<<(l[i][j]-1));clr[i][l[i][j]]=v[l[i][j]][to[i][j]]-v[l[i][j]][0];}}memset(dp,-1,sizeof(dp));dp[0][0][0]=sum;int now_=0;for(int i=0;i<m;i++){for(int j=0;j<=T;j++){for(int S=0;S<(1<<n);S++){dp[now_^1][j][S]=max(dp[now_^1][j][S],dp[now_][j][S]);}}for(int j=0;j<=T-t[i+1];j++){for(int S=0;S<(1<<n);S++){tmp[S]=-1;}for(int rp=1;rp<=n;rp++){if(!(Si[i+1]&(1<<(rp-1)))) continue;for(int S=0;S<(1<<n);S++){if(!(S&(1<<(rp-1)))) {if(dp[now_][j][S]!=-1) tmp[S|(1<<(rp-1))]=max(tmp[S|(1<<(rp-1))],dp[now_][j][S]+clr[i+1][rp]);if(tmp[S]!=-1) tmp[S|(1<<rp-1)]=max(tmp[S|(1<<(rp-1))],tmp[S]+clr[i+1][rp]);}}}for(int S=0;S<(1<<n);S++){dp[now_^1][j+t[i+1]][S]=max(dp[now_^1][j+t[i+1]][S],tmp[S]);}}now_^=1;}for(int i=1;i<=T;i++){sum=0;for(int j=0;j<=i;j++){for(int S=0;S<=(1<<n)-1;S++) sum=max(sum,dp[now_][j][S]);}cout<<sum<<endl;}return 0;
}

其他题代补(也许还会补个 M)

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

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

相关文章

Java REST API 三层架构项目目录规划与使用建议

Java REST API 三层架构项目目录规划与使用建议2025-09-22 22:07 曾左 阅读(0) 评论(0) 收藏 举报一. 背景介绍 当前,我们使用 Spring Boot + Mybatis + Maven 技术栈,按照微服务设计的要求(小而自治)开发 Jav…

典型的四大综合门户网站为食堂写个网站建设

From: http://www.51testing.com/html/44/17144-18146.html 1. 基本概念 实时传输协议&#xff08;RTP&#xff0c;Real-time Transport Protocol&#xff09;是用于Internet上针对多媒体数据流的一种传输协议。传送音视频数据通常都会采用基于UDP的RTP传输&#xff0c;RTP为数…

网站开发看什么书汕头seo专家

场景 NameNode迁移&#xff0c;导致一个节点无法启动 异常 在Namenode主动迁移&#xff0c;或者Namenode机器挂掉无法恢复时&#xff0c;我们需要Namenode节点迁移&#xff0c;迁移经常会出现一个NameNode启动成功&#xff0c;另外一个standby启动失败&#xff0c;报错如下 …

网站建设内链免费装修设计网

风丘科技将首次亮相 EVM ASIA 2023 WINDHILL will debut EVM ASIA 2023 ——可持续移动的未来 —The Future of SUSTAINABLE Mobility EVM ASIA 2023是亚太地区电气化的国际性展会&#xff0c;专注于新能源汽车、充电技术及汽车零件制造等。展会致力于促进包括充电站、交通…

网站内容建设 内容审核流程装修公司网站建设的意义

一、源码特点 asp.net特色商品购物网站系统 是一套完善的web设计管理系统&#xff0c;系统采用mvc模式&#xff08;BLLDALENTITY&#xff09;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为 vs2010&#xff0c;数据库为sqlserver2008&a…

江苏扬州建设局网站网站建设制作好评语

淘宝/天猫获得淘宝商品详情 API 返回值说明 item_get-获得淘宝商品详情 API测试工具 taobao.item_get 公共参数 名称类型必须描述keyString是调用key&#xff08;必须以GET方式拼接在URL中&#xff09;secretString是调用密钥api_nameString是API接口名称&#xff08;包括…

国内有做外汇的正规网站吗关键词排名推广

java.util.concurrent.locks.Lock 接口是Java并发包中的一部分&#xff0c;它提供了比内置锁&#xff08;即 synchronized 关键字&#xff09;更灵活和强大的锁机制。通过使用 Lock 接口及其相关实现类&#xff0c;开发者可以获得更多的功能选项来控制线程间的同步行为&#xf…

如何选择网站开发公司做电影网站多少钱

前言 使用 API 网关作为内部服务面向客户端的单一入口&#xff0c;是一种普遍采用的架构模式。企业组织通过良好定义的 API 将内部系统向内部和外部用户公开&#xff0c;通常都会采用 API 网关来处理横向的关注点&#xff0c;包括访问控制、速率限制、负载均衡等等&#xff0c…

活动策划案怎么写网站优化排名易下拉技术

线程属于某一个进程 共同点&#xff1a;都能并发 线程共享变量&#xff0c;进程不共享。 多线程任务中&#xff0c;其中某一个线程调用了exit了&#xff0c;其他线程会跟着一起退出 如果是特定的线程就调用pthread_exit 失败返回的是错误号 下面也是

2025.9.22总结 - A

今天满课,上午是建模和数据结构,主要讲的还是基础,还有对UML的理解,下午Java,学到了,解决问题的,复杂问题简单化,简单问题流程化的思想,在解决问题时的分类转化思想,让问题更加简单,解决更加高效。

实用指南:GESP三级考纲+三级考试知识点详解

实用指南:GESP三级考纲+三级考试知识点详解pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", &quo…

github操作备忘录

如何使用github1、创建repository在github上创建新的repository2、本地安装Git3、本地全局配置打开git-bash.exe,配置所有Git仓库的用户名和邮箱git config –global user.name "???" git config –glob…

流媒体网站建设规划镇江网站建设机构

Harbor基本介绍 1、Harbor 是 VMware 公司开源的企业级 Docker Registry 项目&#xff0c;Harbor 是一个企业级的 Docker 私有仓库项目。 2、Harbor以 Docker 公司开源的 Registry 为基础&#xff0c;提供了图形管理 UI 、基于角色的访问控制(Role Based AccessControl) 、AD/L…

php 怎么做 网站 图片学校网站建设运行简介

用Maven install 对父工程安装到本地仓库

可以做ppt的网站有哪些内容河南省城乡建设厅官网

1.API 1.1API概述 什么是API API (Application Programming Interface) &#xff1a;应用程序编程接口 java中的API 指的就是 JDK 中提供的各种功能的 Java类&#xff0c;这些类将底层的实现封装了起来&#xff0c;我们不需要关心这些类是如何实现的&#xff0c;只需要学习这…

网站建设捌金手指下拉二七冷水滩网站建设

文章主题&#xff1a;有序序列合并&#x1f525;&#x1f525;&#x1f525;所属专栏&#xff1a;C语言每日一题&#x1f4d7;作者简介&#xff1a;每天不定时更新C语言的小白一枚&#xff0c;记录分享自己每天的所思所想&#x1f604;&#x1f3b6;个人主页&#xff1a;[₽]的…

熟练掌握网站开发技术网站开发经验

来源&#xff1a;之江实验室、仿生深海软体机器人项目组、浙江大学▍适应万米静水压的软体机器人由于极端的静水压力&#xff0c;深海区域人们基本很难探测。位于西太平洋的马里亚纳海沟是已知的海洋最深处&#xff0c;水压高、温度低、完全黑暗&#xff0c;被称为“地球第四极…

网站阴影黔南州建设局网站

1. 说一下CSS的盒模型。 在HTML页面中所有的元素都可以看成是一个盒子。 盒子的组成&#xff1a;内容content、内边距padding、边框border、外边距margin。 盒模型的类型&#xff1a; 标准盒模型&#xff1a;width contentIE盒模型&#xff08;怪异盒模型&#xff09;&#…

如何自建网站做外贸做网站图片无法显示的原因

说到贝塞尔曲线&#xff0c;大家肯定都不陌生&#xff0c;网上有很多关于介绍和理解贝塞尔曲线的优秀文章和动态图。以下两个是比较经典的动图了。二阶贝塞尔曲线&#xff1a;三阶贝塞尔曲线&#xff1a;由于在工作中经常要和贝塞尔曲线打交道&#xff0c;所以简单说一下自己的…

南山网站公司石家庄p2p网站开发

1.论文介绍 MAS-SAM: Segment Any Marine Animal with Aggregated Features MAS-SAM&#xff1a;利用聚合特征分割任何海洋动物 Paper Code(空的) 2.摘要 最近&#xff0c;分割任何模型&#xff08;SAM&#xff09;在生成高质量的对象掩模和实现零拍摄图像分割方面表现出卓越…