CF1654F-Minimal String Xoration【倍增】

1|0正题

题目链接:https://www.luogu.com.cn/problem/CF1654F


1|1题目大意

给出一个长度为2n的字符串s(下标为02n1

你要找到一个x满足ti=si xor x,并且t的字典序最小。

1n18


1|2解题思路

考虑设f(i,x)表示选的值为x时,最终的t的前2i个字符。

那么我们有

f(i,x)=f(i1,x)+f(i1,x xor 2i1)

(就是和另一边拼起来)

发现这个部分和SA的有点像,我们考虑倍增来做,枚举这个i

假设我们已经得到所有f(i1,x)的排名,那么当我们比较f(i,x)f(i,y)时,优先比较f(i1,x)f(i1,y),如果相等那么比较f(i1,x xor 2i1)f(i1,y xor 2i1)即可。

然后我们又可以O(1)比较然后O(2nn)得出新的i的所有f(i,x)的排名。

时间复杂度:O(2nn2)


1|3code

#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int N=1<<18; int n,m,r,p[N],a[N],b[N]; char s[N]; bool cmp(int x,int y){ if(a[x]==a[y])return a[x^r]<a[y^r]; return a[x]<a[y]; } int main() { scanf("%d",&n);m=(1<<n); scanf("%s",s); for(int i=0;i<m;i++)p[i]=i; for(int i=0;i<m;i++)a[i]=s[i]-'a'; sort(p,p+m,cmp); for(int i=0;i<n;i++){ r=1<<i; sort(p,p+m,cmp);b[p[0]]=1; for(int j=1;j<m;j++) b[p[j]]=b[p[j-1]]+cmp(p[j-1],p[j]); for(int j=0;j<m;j++)a[j]=b[j]; } for(int i=0;i<m;i++) printf("%c",s[i^p[0]]); return 0; }

__EOF__

本文作者QuantAsk
本文链接https://www.cnblogs.com/QuantAsk/p/16063687.html
关于博主:退役OIer,GD划水选手
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   QuantAsk  阅读(37)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 张高兴的大模型开发实战:(一)使用 Selenium 进行网页爬虫
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
历史上的今天:
2021-03-27 牛客练习赛79E-小G的数学难题【dp,单调队列】
2021-03-27 P4707-重返现世【dp,数学期望,扩展min-max容斥】
点击右上角即可分享
微信分享提示