博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
CF79D Password
阅读量:5923 次
发布时间:2019-06-19

本文共 2391 字,大约阅读时间需要 7 分钟。

 

挺巧妙的题

看起来无从下手

k很小,先不管

把最终需要亮的看做1,不需要的看做0

要把全0序列,变成有至多10个1的01序列

不妨考虑把01序列变回全0序列(这样容易思考)

区间取反?

差分变成两个单点取反!

特殊加入n+1位置,这样便于取反

 

首先,两个0取反一定不优,可以用01取反和11取反来得到相同的效果

01取反,等价于1走到0,11取反,等价于两个1消掉。

不断两个位置进行取反,一定是为了最后把两个1消掉!

也就是,其实是两个1的匹配

 

1一共只有20个

最短路建图,f[i][j]表示i和j匹配的最小代价,也即最短路

一个问题是:不会影响其他位置的值吗?

发现这个最短路的边,除了起点终点,都恰好xor两次(虽然这样并不优)!不会影响其他的位置的值!

BFS求最短路

然后Dp即可

枚举和S的lowbit进行匹配的点

O(20*2^20)

#include
#define reg register int#define il inline#define fi first#define se second#define mk(a,b) make_pair(a,b)#define numb (ch^'0')#define pb push_back#define solid const auto &#define enter cout<
using namespace std;typedef long long ll;template
il void rd(T &x){ char ch;x=0;bool fl=false;while(!isdigit(ch=getchar()))(ch=='-')&&(fl=true); for(x=numb;isdigit(ch=getchar());x=x*10+numb);(fl==true)&&(x=-x);}template
il void output(T x){
if(x/10)output(x/10);putchar(x%10+'0');}template
il void ot(T x){
if(x<0) putchar('-'),x=-x;output(x);putchar(' ');}template
il void prt(T a[],int st,int nd){ for(reg i=st;i<=nd;++i) ot(a[i]);putchar('\n');}namespace Modulo{const int mod=998244353;int ad(int x,int y){ return (x+y)>=mod?x+y-mod:x+y;}void inc(int &x,int y){x=ad(x,y);}int mul(int x,int y){ return (ll)x*y%mod;}void inc2(int &x,int y){x=mul(x,y);}int qm(int x,int y=mod-2){ int ret=1;while(y){ if(y&1) ret=mul(x,ret);x=mul(x,x);y>>=1;}return ret;}}//using namespace Modulo;namespace Miracle{const int N=10000+5;const int M=105;const int K=22;const int inf=0x3f3f3f3f;int n,k,m;int pos[K],dis[N],cnt;int f[K][K];int a[N],b[N];int dp[(1<<20)+23];int q[N],l,r;void bfs(int st){ memset(dis,0x3f,sizeof dis); dis[pos[st]]=0; l=1,r=0; q[++r]=pos[st]; while(l<=r){ int x=q[l++]; for(reg i=1;i<=m;++i){ int to=x+b[i]; if(to<=n+1&&dis[to]>dis[x]+1){ dis[to]=dis[x]+1; q[++r]=to; } to=x-b[i]; if(to>0&&dis[to]>dis[x]+1){ dis[to]=dis[x]+1; q[++r]=to; } } } for(reg i=1;i<=cnt;++i){ f[st][i]=dis[pos[i]]; }}int num(int p){ int sz=__builtin_ctz(p); return sz+1;}int main(){ rd(n);rd(k);rd(m); for(reg i=1;i<=k;++i){ int x;rd(x); a[x]=1; } for(reg i=1;i<=m;++i){ rd(b[i]); } for(reg i=n+1;i>=1;--i){ a[i]^=a[i-1]; if(a[i]==1) pos[++cnt]=i; } // prt(a,1,n+1); // prt(pos,1,cnt); for(reg i=1;i<=cnt;++i){ // cout<<" bfs i------------ "<
<

 

转载于:https://www.cnblogs.com/Miracevin/p/10933169.html

你可能感兴趣的文章
CF 291E. Tree-String Problem [dfs kmp trie图优化]
查看>>
json转字符串 —— jsonObj.toJSONString()与JSON.stringify(jsonObj)
查看>>
mysql linux下表名忽略大小写注意事项
查看>>
springmvc的声明式事务管理类型讲解
查看>>
Unable to cast object of type 'System.Int32' to type 'System.Array'.
查看>>
Linux下双网卡绑定bond0【转】
查看>>
Mybatis(一) mybatis入门
查看>>
EM 算法 实例
查看>>
深入理解javascript闭包【整理】
查看>>
Color Schema 配色随笔
查看>>
spring-cloud: eureka之:ribbon负载均衡配置(一)
查看>>
英语语法总结---一、英语中定语放在哪
查看>>
[转]npm、 cnpm、yarn
查看>>
净推荐值(NPS):用户忠诚度测量的基本原理及方法
查看>>
我终于开通了微信公众号
查看>>
Spring3:AOP
查看>>
如何将本地的项目上传到git
查看>>
java结合testng,利用mysql数据库做数据源的数据驱动实例
查看>>
C# 多线程学习系列四之ThreadPool取消、超时子线程操作以及ManualResetEvent和AutoResetEvent信号量的使用...
查看>>
银行传统支付通道与支付平台结合
查看>>