当前位置: 首页 > news >正文

2023ICPC合肥题解

文章目录

  • F. Colorful Balloons(签到)
  • E. Matrix Distances(思维+小结论)
  • J. Takeout Delivering(最短路)
  • G. Streak Manipulation(二分+dp)
  • C. Cyclic Substrings(回文自动机)

题目链接

F. Colorful Balloons(签到)

在这里插入图片描述

    int n;cin>>n;for(int i=1;i<=n;i++) cin>>s[i];map<string,int> mp;for(int i=1;i<=n;i++){mp[s[i]]++;if(mp[s[i]]*2 > n){cout<<s[i];return;}}cout<<"uh-oh";

E. Matrix Distances(思维+小结论)

在这里插入图片描述
经典的x和y可以分开算

    int n,m;cin>>n>>m;vector<int> nums;for(int i=1;i<=n;i++)for(int j=1;j<=m;j++){cin>>c[i][j];nums.push_back(c[i][j]);}sort(nums.begin(),nums.end());nums.erase(unique(nums.begin(),nums.end()),nums.end());for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){c[i][j]=lower_bound(nums.begin(),nums.end(),c[i][j])-nums.begin();}}int ans=0;vector<int> num(nums.size()+1),sum(nums.size()+1);for(int j=1;j<=m;j++) //for(int i=1;i<=n;i++){ans+=num[c[i][j]]*j - sum[c[i][j]];sum[c[i][j]]+=j;num[c[i][j]]++;}for(int i=0;i<nums.size()+1;i++)num[i]=sum[i]=0;for(int i=1;i<=n;i++) //for(int j=1;j<=m;j++){ans+=num[c[i][j]]*i - sum[c[i][j]];sum[c[i][j]]+=i;num[c[i][j]]++;}cout<<ans*2;

J. Takeout Delivering(最短路)

在这里插入图片描述
题意:

1 1 1走到 n n n,路径大小为最大的两条边的边权和

思路:

分别从 1 , n 1,n 1n开始记录到每个点的最大值

枚举最大边,那么答案就是 min ⁡ ( w + max ⁡ ( d i s 1 , u , d i s v , n ) ) ( max ⁡ ( d i s 1 , u , d i s v , n ) ≤ w ) \min (w+\max(dis_{1,u},dis_{v,n}))(\max(dis_{1,u},dis_{v,n}) \leq w) min(w+max(dis1,u,disv,n))(max(dis1,u,disv,n)w)

void solve(){int n,m;cin>>n>>m;vector<PII> adj[n+1];int ans=INF;vector<array<int,3>> e;for(int i=1;i<=m;i++){int u,v,w;cin>>u>>v>>w;if((u==1&&v==n)||(u==n&&v==1))ans=min(ans,w);adj[u].push_back({v,w});adj[v].push_back({u,w});e.push_back({u,v,w});}vector<int> vis(n+1);auto dijk=[&](vector<int> &dis,int st){priority_queue<PII,vector<PII>,greater<PII>> pq;dis[st]=0;vis.assign(n+1,0);pq.push({0,st});while(!pq.empty()){auto [d,u]=pq.top();pq.pop();if(vis[u])continue;vis[u]=1;for(auto [v,w]:adj[u]){int x=(dis[u]==0?w:max(dis[u],w));if(dis[v]>x){dis[v]=x;pq.push({dis[v],v});}}}};vector<int> dis1(n+1,INF),dis2(n+1,INF);dijk(dis1,1);dijk(dis2,n);for(auto [u,v,w]:e){if(dis1[u]<=w&&dis2[v]<=w)ans=min(ans,w+max(dis1[u],dis2[v]));if(dis1[v]<=w&&dis2[u]<=w)ans=min(ans,w+max(dis1[v],dis2[u]));}cout<<ans<<"\n";
}

G. Streak Manipulation(二分+dp)

在这里插入图片描述
给一个01字符串,问最大长度 l l l,这样的连续 1 1 1的不相连接线段至少有 k k k个,最多可以修改 m m m 0 0 0 1 1 1

很明显可以二分答案,并且 k k k很小可以直接dp

d p i , j dp_{i,j} dpi,j表示考虑完前 i i i个字母,构成了 j j j段长度为 l l l的线段,判断条件就是 d p n , k ≤ m dp_{n,k} \leq m dpn,km

转移的时候我们枚举每个线段的合法右端点,然后获取大于等于 l l l的线段的左端点(这一部分最易出错,考虑各种边界即可,比如左右端点在原有的线段内,或者如果当前端点置1导致两个线段合并在一起不符和假设的左端点或右端点时,需要更新以下)

复杂度 O ( n log ⁡ 2 n ) O(n \log^2n) O(nlog2n),实现好一点可以 O ( n log ⁡ n ) O(n \log n) O(nlogn)

int n,m,k;
vector<PII> seg;
int sum[N];
bool check(int x){vector dp(n+1,vector<int>(k+1,INF));dp[0][0]=0;for(int i=1;i<=n;i++){for(int j=0;j<=k;j++)dp[i][j]=dp[i-1][j];auto it=upper_bound(seg.begin(),seg.end(),PII{i,INF});if(it!=seg.end()&&it->F-1==i)continue;if(it!=seg.begin()){it--;if(it->F<=i&&i<=it->S&&i!=it->S)continue;}int l=i-x+1;if(l<1)continue;it=upper_bound(seg.begin(),seg.end(),PII{l,INF});if(it!=seg.begin()){it--;if(l<=it->S+1)l=it->F;}int pos=l==1?0:l-2;for(int j=1;j<=k;j++){if(dp[pos][j-1]==INF)continue;dp[i][j]=min(dp[i][j],dp[pos][j-1]+sum[i]-sum[l-1]);}}return dp[n][k]<=m;
}
void solve(){cin>>n>>m>>k;string s;cin>>s;s=" "+s;for(int i=1;i<=n;i++)sum[i]=sum[i-1]+(s[i]=='0');for(int i=1,j;i<=n;i++){if(s[i]=='0')continue;j=i;while(j+1<=n&&s[j+1]==s[j])j++;seg.push_back({i,j});i=j;}int l=0,r=n;while(l<r){int mid=l+r+1>>1;if(check(mid))l=mid;else r=mid-1;}cout<<(l==0?-1:l);
} 

C. Cyclic Substrings(回文自动机)

在这里插入图片描述
t t t为循环本质不同回文子串, f ( t ) f(t) f(t)表示出现次数, g ( t ) g(t) g(t)表示长度,求 ∑ f ( t ) 2 g ( t ) \sum f(t)^2g(t) f(t)2g(t)

回文自动机板子题,令新串为 S = S S S=SS S=SS,那么就可以求出来 S S S的回文自动机,当前的回文串是有效的当下标 i > n i \gt n i>n

然后在fail树上做一遍累加,最后统计答案

struct PAM{static constexpr int ALPHABET_SIZE=10;struct Node{int len,link,cnt;// cnt表示以当前字符结尾的不同子串个数(视实际情况而定)array<int,ALPHABET_SIZE> next;};vector<Node> t;int suff;string s;PAM(){init();}void init(){t.assign(2,Node());t[0].len=-1;suff=1;s.clear();}int newNode(){t.emplace_back();return t.size()-1;}bool add(int c){int pos=s.size();s+=c;c=c-'0';int cur=suff,curlen=0;while(true){curlen=t[cur].len;if(pos-1-curlen>=0&&s[pos-1-curlen]==s[pos])break;cur=t[cur].link;}if(t[cur].next[c]){suff=t[cur].next[c];return false;}suff=newNode();t[suff].len=t[cur].len+2;t[cur].next[c]=suff;if(t[suff].len==1){t[suff].link=1;return true;}while(true){cur=t[cur].link;curlen=t[cur].len;if(pos-1-curlen>=0&&s[pos-1-curlen]==s[pos]){t[suff].link=t[cur].next[c];break;}}return true;}int next(int p,int c){return t[p].next[c-'0'];}int link(int p){return t[p].link;}int len(int p){return t[p].len;}int cnt(int p){return t[p].cnt;}int size(){return t.size();}
} pam;
void solve(){int n;cin>>n;string s;cin>>s;s+=s;auto &t=pam.t;for(int i=0;i<s.size();i++){pam.add(s[i]);if(i>n-1)t[pam.suff].cnt++;}for(int i=t.size()-1;i>=2;i--){t[t[i].link].cnt+=t[i].cnt;}LL ans=0;for(int i=2;i<t.size();i++){if(t[i].len<=n)ans+=1ll*t[i].cnt*t[i].cnt%mod*t[i].len%mod,ans%=mod;}cout<<ans<<"\n";
}   

相关文章:

  • 深入解读:2024数据资产场景化评估案例手册(第二期)【附全文阅读】
  • Linux中的系统延时任务和定时任务与时间同步服务和构建时间同步服务器
  • 大模型的scaling laws:Scaling Laws for Neural Language Models
  • Prompt Engineering 提示工程:释放大语言模型潜力的关键技术与实践指南
  • 大语言模型(LLMs)微调技术总结
  • TensorFlow深度学习实战——基于循环神经网络的文本生成模型
  • es+kibana---集群部署
  • vscode 使用gitcode团队管理项目
  • 推荐一个微软官方开源浏览器自动化工具,可以用于UI自动化测试、爬虫等,具备.Net、Java、Python等多个版本!
  • Flutter介绍、Flutter Windows Android 环境搭建 真机调试
  • Python实现SSE流式推送
  • 【蒸馏(5)】DistillBEV代码分析
  • 关于华为云OneAccess登录认证过程介绍
  • 论文阅读_Search-R1_大模型+搜索引擎
  • Maven多模块工程版本管理:flatten-maven-plugin扁平化POM
  • 深入浅出限流算法(二):更平滑的滑动窗口
  • MATLAB小试牛刀系列(1)
  • 【前端】1h 搞定 TypeScript 教程_只说重点
  • 并发设计模式实战系列(8):Active Object
  • ArcPy 中的地理处理工具
  • 杭州打造商业航天全产业链,请看《浪尖周报》第22期
  • 释新闻|SEVIS是什么?在美留学生遭身份中止意味什么?
  • 从世界工厂走向全球创新中心,上海车展为何成为全球汽车行业风向标?
  • “世纪火种”嘉年华启动,69家单位加入阅读“朋友圈”
  • 锚定“双一流”战略坐标,福建农林大学向全球英才“伸出橄榄枝”
  • 证监会发布上市公司信披豁免规定:明确两类豁免范围、规定三种豁免方式