CF884F - Anti-Palindromize
我们发现这个题的数据范围、“字符和位置匹配”再加上一条奇怪的限制,长得就很网络流,那么就考虑如何用网络流做。
考虑重新解释一下这个题面,其实就是:给定一个字符集和 \(n\) 个位置进行匹配,其中,字符 \(ch\) 到位置 \(i\) 的边和字符 \(ch\) 到位置 \(n-i+1\) 的边只能选一个。对于一个匹配可能会有边权,具体而言,位置 \(i\) 和字符 \(ch\) 匹配边的权值是 \(b_i\cdot[s_i=ch]\)。求一个最大权值的匹配。
我们已经将题意转化成很贴近费用流的样子了,唯一的问题在于“字符 \(ch\) 到 \(i\) 的边和字符 \(ch\) 到 \(n-i+1\) 的边只能选一个”很难搞。
考虑增加一组点用于限制,限制点 \((ch,i)(i\le \dfrac{n}{2})\) 是一个从 \(ch\) 连到 \(i\) 和 \(n-i+1\) 必须经过的点。而从 \(ch\) 到 \(i\) 和 \(n-i+1\) 最多有一个流量,所以点 \(ch\) 到 \((ch,i)\) 的流量是 \(1\),就解决了两条边只能选一个的问题。再从 \((ch,i)\) 连到 \(i\) 和 \(n-i+1\),边权还是一样计算,唯一的不同就是 \(ch\) 出发的流量只能到达 \(i\) 和 \(n-i+1\) 其中之一。
我们就得到了一个最大费用最大流的问题,把边权设成负的就变成普通的费用流。设 \(\sigma=26\),点数是 \(2+\sigma+n+\dfrac{\sigma n}{2}\),边数是 \(\sigma+n+\dfrac{3\sigma n}{2}\),流量是 \(n\),总的复杂度是 \(O(\sigma^2n^3)\),但是网络流一般跑不满,实际表现只跑了 31ms
。
//因为本人的习惯,费用流是封的板子,解释一下主函数中调用的部分:
//Juc::ptt(i)是在图中加上编号为i的点
//Juc::add(a,b,c,d)是在图中加上从a到b,流量为c,费用为d的边和反向边
//Juc::s是源点
//Juc::t是汇点
//Juc::MCMF()是跑费用流
//Juc::cost是运行出来的费用
#define rd(i,n) for(int i=0;i<n;i++)
#define rp(i,n) for(int i=1;i<=n;i++)
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define per(i,a,b) for(int i=b;i>=a;i--)
#define st string
#define vt vector
#define pb push_back
typedef long long ll;
namespace Juc{
int n,m,s,t,a,b,c,d;
vt<int>pnts;
int dep[200005],vis[200005],cur[200005],dist[200005],vist[200005];
struct edge{
int a,b,f,c;
edge(int _a,int _b,int _f,int _c){
a=_a,b=_b,f=_f,c=_c;
};
};
vt<edge>ve;
vt<int>vv[200005];
inline void add(int a,int b,int c,int d){
ve.pb(edge(a,b,c,d));
ve.pb(edge(b,a,0,-d));
vv[a].pb(ve.size()-2);
vv[b].pb(ve.size()-1);
}
inline void ptt(int a){
pnts.pb(a);
}
inline bool SPFA(){
for(auto i:pnts)dist[i]=1e9,vist[i]=0,vis[i]=0,cur[i]=0;
queue<int>q;
q.push(s),vist[s]=1,dist[s]=0;
while(q.size()){
int i=q.front();
q.pop();
vist[i]=0;
for(auto g:vv[i]){
auto &e=ve[g];
if(e.f&&dist[i]+e.c<dist[e.b]){
dist[e.b]=dist[i]+e.c;
if(!vist[e.b]){
vist[e.b]=1;
q.push(e.b);
}
}
}
}
return dist[t]!=1e9;
}
int cost=0;
inline int DFS(int i,int f){
if(i==t||f==0)return f;
vis[i]=1;
int res=0;
for(int j=cur[i];j<vv[i].size();j++){
edge& e=ve[vv[i][j]];
cur[i]=j;
if(!vis[e.b]&&dist[e.b]==dist[i]+e.c&&e.f){
ll flow=DFS(e.b,min(e.f,f));
ve[vv[i][j]].f-=flow,ve[vv[i][j]^1].f+=flow;
f-=flow,res+=flow;
cost+=flow*e.c;
}
if(!f)break;
}
vis[i]=0;
return res;
}
inline int MCMF(){
int ans=0;
while(SPFA()){
ans+=DFS(s,1e9);
}
return ans;
}
}
int n,b[105],cnt[26];
st s;
signed main(){
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
cin>>n>>s;s='$'+s;
rp(i,n)cin>>b[i];
rp(i,n)cnt[s[i]-'a']++;
//建立源点
Juc::ptt(0);Juc::s=0;
//建立字符点和初始流量
rd(i,26)Juc::ptt(i+1),Juc::add(0,i+1,cnt[i],0);
//建立位置点
rp(i,n)Juc::ptt(26+i);
//建立限制点
rp(i,n/2)rd(j,26){
int cur=26+n+(i-1)*26+j+1;
Juc::ptt(cur);
//通过流量为1进行限制
Juc::add(j+1,cur,1,0);
//连贡献边
Juc::add(cur,26+i,1,-b[i]*(j+'a'==s[i]));
Juc::add(cur,26+n-i+1,1,-b[n-i+1]*(j+'a'==s[n-i+1]));
}
//建立汇点和最终流量
int tot=26+n+n*26+1;
Juc::t=tot;Juc::ptt(tot);
rp(i,n)Juc::add(26+i,tot,1,0);
Juc::MCMF();
cout<<-Juc::cost<<endl;
return 0;
}
//Crayan_r
CF884F - Anti-Palindromize的更多相关文章
- ABP Zero示例项目登录报错“Empty or invalid anti forgery header token.”问题解决
ABP Zero项目,登录时出现如图"Empty or invalid anti forgery header token."错误提示的解决方法: 在 WebModule.cs的P ...
- 【CF884F】Anti-Palindromize 费用流
[CF884F]Anti-Palindromize 题意:定义一个串是反回文的,当且仅当对于1<=i<=len,$a_i!=a_{len-i+1}$. 现在给出一个长度为n的串S(n是偶数 ...
- 【黑客免杀攻防】读书笔记18-最终章Anti Rootkit
1.免杀技巧的遏制 1.1.PE文件 入口点不在第一个区段或在最后一个区段 入口点处代码附近只有一小段代码 入口点在正常范围之外 入口点为一个无效的值,实际入口点为TLS的入口点 区段名重复或者不属于 ...
- 智课雅思词汇---十四、ante,anti不仅是词根还是前缀
智课雅思词汇---十四.ante,anti不仅是词根还是前缀 一.总结 一句话总结:来源于拉丁语 ante 前.词根ant 为 anti 的变体.ante,anti不仅是词根还是前缀. 词根:ante ...
- js & anti craw & crawler spam
js & anti craw & crawler spam demo & X-Sign , function(t, e, n) { "use strict" ...
- Anti XSS 防跨站脚本攻击库
https://wpl.codeplex.com/ Before understanding Anti-Cross Site Scripting Library (AntiXSS), let us u ...
- 页面发送请求到后台报错“Empty or invalid anti forgery header token.”问题解决
在页面向后台发送请求时,报如上图的错误的解决办法: 在WebModule.cs类中的PreInitialize方法中加 Configuration.Modules.AbpWeb().AntiForge ...
- IMPLEMENTATION - Entity Framework Anti Pattern - High Performance EF
Good about ORM Developer is free from building T-Sql on the database tier which is not their major a ...
- hdu 1907 John (anti—Nim)
John Time Limit: 5000/1000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)http://acm.h ...
- 基于 od 窗口的anti
虽然 odadvance 这类的插件 , 使用驱动将 od 的窗口 进行 隐藏,使用enumwindow ,无法枚举到od的窗口, 但是依然可以 使用r3 的方法 , 对od 窗口检测 之后可以使用 ...
随机推荐
- MySQL简介、下载、密码修改及基本使用
目录 存取数据的演变史 数据库软件应用史 数据库的本质 数据库的分类 MySQL简介 MySQL基本使用 系统服务的制作 密码相关操作 SQL与NoSQL 数据库重要概念 基本SQL语句 存取数据的演 ...
- UVA 673 Paretheses Balance
原题Vjudge 题目大意 怼给你一堆括号,判断是否合法 有三条规则 (1)空串合法 (2)如果\(A和B\)都合法,则\(AB\)合法(例如:\(()和[]\)都合法,则\(()[]\)合法) (3 ...
- 可视化—AntV G6 高亮相邻节点的两种方式
目录 内置的高亮节点 自定义高亮 自定义高亮时保持原始颜色 总结 案例完整代码 通过官方文档,可知高亮相邻节点分为两种方法,文档描述并不是很清楚,对刚接触这个库的小白并不是很友好,慢慢总结慢慢来吧 内 ...
- 90%的Java开发人员都会犯的5个错误
前言 作为一名java开发程序员,不知道大家有没有遇到过一些匪夷所思的bug.这些错误通常需要您几个小时才能解决.当你找到它们的时候,你可能会默默地骂自己是个傻瓜.是的,这些可笑的bug基本上都是你忽 ...
- [python] 基于NetworkX实现网络图的绘制
NETWORK CHART(网络图) 代码下载地址 网络图 (或图表或图形)显示了一组实体之间的互连.每个实体由一个或多个节点表示.节点之间的连接通过链接(或边)表示.网络的理论与实现是一个广阔的研究 ...
- [编程基础] Python中的绝对导入与相对导入
如果您从事的Python项目有多个文件,那么您以前可能不得不使用import语句.即使对于拥有多个项目的Python重度使用者(比如我),import也可能会造成混淆!您可能正在阅读本文,因为您想对P ...
- [编程基础] C++多线程入门7-条件变量介绍
原始C++标准仅支持单线程编程.新的C++标准(称为C++11或C++0x)于2011年发布.在C++11中,引入了新的线程库.因此运行本文程序需要C++至少符合C++11标准. 文章目录 7 条件变 ...
- Ansible 学习笔记 - 定位主机和组的模式
中英文对照表 英文 中文 备注 host 主机 group (主机)组 pattern 模式 ad hoc 特别命令 playbook 剧本 Ansible 专有名词,一段复杂的编排 inventor ...
- forms组件渲染标签、展示信息、校验数据的一些补充,forms组件参数和源码剖析,modelform组件,Django中间
今日内容 forms组件渲染标签 forms组件渲染标签的方式1 <p>forms组件渲染标签的方式1</p> {{ form_obj.as_p }} {{ form_obj. ...
- 均有商业公司支持!2023再看数据湖 hudi iceberg delta2 社区发展现状!
开源数据湖三剑客 Apache hudi.Apache iceberg .Databricks delta 近年来大动作不断. 2021年8月,Apache Iceberg 的创始人 Ryan Blu ...