BZOJ 2160: 拉拉队排练
来源:互联网 发布:淘宝实名制可以改吗 编辑:程序博客网 时间:2024/04/29 18:29
双倍经验题
manacher/palindromic tree
对于manacher的话显然回文串的长度最多只有n种,对于每个奇数长度的位置显然长度为1,3,5.....r[i]的串的个数都+1,区间加减什么的差分一下前缀和搞一搞就好了
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<vector>#include<cmath>using namespace std;#define rep(i,l,r) for(int i=l;i<=r;i++)#define per(i,r,l) for(int i=r;i>=l;i--)#define mmt(a,v) memset(a,v,sizeof(a))const int N=1000000+5;const int p=19930726;typedef long long ll;char s[N<<1],t[N];int r[N<<1],n;ll cnt[N],k;void manacher(){ int m=n<<1|1; rep(i,1,m) if(i&1)s[i]='#'; else s[i]=t[i>>1]; int id,mx=0; rep(i,1,m){ if(mx>i)r[i]=min(mx-i,r[2*id-i]); else r[i]=1; while(i-r[i]>=1&&i+r[i]<=m&&s[i-r[i]]==s[i+r[i]])r[i]++; if(~r[i]&1)cnt[(r[i]>>1)]++; if(i+r[i]>mx)mx=i+r[i],id=i; }}ll qmul(ll a,ll b){ ll ans=1; for(;b;b>>=1,a=a*a%p)if(b&1)ans=ans*a%p; return ans;}int solve(){ manacher(); ll ans=1; per(i,n,1){ cnt[i]+=cnt[i+1]; if(cnt[i]<=k){ k-=cnt[i]; (ans*=qmul(2*i-1,cnt[i]))%=p; }else (ans*=qmul(2*i-1,k))%=p,k=0; if(!k)return ans; } return -1;}int main(){ //freopen("a.in","r",stdin); scanf("%d%lld",&n,&k); scanf("%s",t+1); printf("%d\n",solve()); return 0;}
回文树就是裸题了,lazytag打一打,逆序更新一下就好了(由于我比较懒就没基数排序QAQ结果就是nlogn了,好像慢了5倍左右)
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<vector>#include<cmath>using namespace std;#define rep(i,l,r) for(int i=l;i<=r;i++)#define per(i,r,l) for(int i=r;i>=l;i--)#define mmt(a,v) memset(a,v,sizeof(a))const int N=1000000+5;const int p=19930726;typedef long long ll;ll qmul(ll a,ll b){ ll ans=1; for(;b;b>>=1,a=a*a%p)if(b&1)ans=ans*a%p; return ans;}struct Node{ int len,suf,ch[26]; ll sum; bool operator < (const Node &x)const{ return len>x.len; }}tr[N];int last,node;void init(){last=node=2;tr[tr[tr[2].suf=1].suf=1].len=-1;}char s[N];void add(int i){ int cur=last,c=s[i]-'a'; while(s[i-tr[cur].len-1]!=s[i])cur=tr[cur].suf; if(!tr[cur].ch[c]){ tr[last=++node].len=tr[cur].len+2;tr[cur].ch[c]=last; int tmp=tr[cur].suf; while(s[i-tr[tmp].len-1]!=s[i])tmp=tr[tmp].suf; tr[last].suf=tr[last].len==1?2:tr[tmp].ch[c]; } last=tr[cur].ch[c];tr[last].sum++;}int n;ll k;int solve(){ ll ans=1; rep(i,1,node){ if(tr[i].len<=0)continue; if(~tr[i].len&1)continue; if(tr[i].sum<=k) (ans*=qmul(tr[i].len,tr[i].sum))%=p,k-=tr[i].sum; else (ans*=qmul(tr[i].len,k))%=p,k=0; if(!k)return ans; } return -1;}int main(){ //freopen("a.in","r",stdin); scanf("%d%lld %s",&n,&k,s+1); init(); rep(i,1,n)add(i); //rep(i,1,node)printf("%d\n",tr[i].len); per(i,node,1)tr[tr[i].suf].sum+=tr[i].sum; sort(tr+1,tr+1+node); printf("%d\n",solve()); return 0;}
0 0
- BZOJ 2160 拉拉队排练
- BZOJ 2160: 拉拉队排练
- BZOJ 2160: 拉拉队排练
- bzoj 2160 拉拉队排练
- BZOJ 2160: 拉拉队排练 manacher
- BZOJ 2160 拉拉队排练 Manacher + 前缀和
- 【BZOJ 2160】拉拉队排练 回文树
- bzoj 2160: 拉拉队排练 manachar+快速幂
- [BZOJ]2160 拉拉队排练 Manacher+快速幂
- [BZOJ 2160] 拉拉队排练 Manacher+贪心
- HYSBZ 2160 拉拉队排练
- 2160: 拉拉队排练
- 回文树——BZOJ 2160: 拉拉队排练
- bzoj 2160: 拉拉队排练 (manacher+前缀和+快速幂)
- BZOJ 2160 拉拉队排练 (Manacher 序列差分)
- 拉拉队排练
- [BZOJ 2160] 拉拉队排练 (manacher+差分数组+前缀和)
- HYSBZ 2160 拉拉队排练(回文树)
- 查看开源项目org.gradle.api.internal.project.ProjectInternal.getPluginManager()Lorg/gradle/api/internal/plu
- 高质量C编程00-汇总
- hdu1026Ignatius and the Princess I(BFS + 优先队列)
- java 图片压缩和分辨率处理
- 基于ReentrantLock封装的字符串锁的场景与实现
- BZOJ 2160: 拉拉队排练
- Quartz学习总结(1)——Spring集成Quartz框架
- 浙大 PAT Advanced level 1025. PAT Ranking (25)
- poj1325 air raid
- 用原生javascript写出jquery中slideUp和slideDown效果
- logback 配置详解(一)
- C++中substr函数的用法
- tomcat通过urlwrite.xml做301跳转
- 消除恒流源不稳定或电阻分压非线性的影响