BZOJ4406 WC2016 论战捆竹竿
Problem
Solution
显然是一个同余系最短路问题,转移方案就是所有|S|-border的长度,有 \(O(n)\) 种,暴力跑dijkstra的复杂度为 \(O(n^2\log n)\) 。
有一个结论,一个字符串的border的长度可以被分为 \(\log |S|\) 个等差数列。
那么我们不如来考虑一个等差数列所造成的影响,设等差数列共有 \(m\) 项,初值为 \(x\) ,那么它可以被表示为 \(\{ kd+x,k\in[0,m)\}\)
\]
如果我们能建立一个 \(\bmod x\) 的剩余系,那么接下来就相当于添加了一个 \(+d\) 的转移方案,但是这个转移有距离的限制。注意到能相互更新的状态会形成 \(\gcd(x,d)\) 个环,可以套路地拆下来并倍长,用单调队列即可解决距离的限制,时间复杂度为 \(O(x)\)。
那么就只需要解决两个剩余系相互转化的问题了。其实很简单,设旧表的模数为 \(p\),新表的模数为 \(q\),只需要把旧表中每一列的最小能表达的值作为初始值放入新表中,然后只需要把转移方案 \(+p\) 加入表中,更新一次即可,这样的复杂度是 \(O(q)\) 的。
总的时间复杂度为 \(O(\sum n\log n)\)
注意把用来存border的数组,把a[len+1]的值清为0,这样才不会导致判的等差数列。
Code
#include <algorithm>
#include <cstring>
#include <cstdio>
using namespace std;
typedef long long ll;
const int maxn=500010;
template <typename Tp> inline int getmin(Tp &x,Tp y){return y<x?x=y,1:0;}
template <typename Tp> inline int getmax(Tp &x,Tp y){return y>x?x=y,1:0;}
template <typename Tp> inline void read(Tp &x)
{
x=0;int f=0;char ch=getchar();
while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
if(ch=='-') f=1,ch=getchar();
while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
if(f) x=-x;
}
int z,n,k,tot,top,now,nxt[maxn],a[maxn],stk[maxn<<1];
int l,r,q[maxn<<1];
ll w,ans,f[maxn],g[maxn];
char s[maxn];
int gcd(int a,int b){return b?gcd(b,a%b):a;}
void trans(int x)
{
int D=gcd(x,now);
memset(g,0x3f,x<<3);
for(int i=0;i<now;i++) getmin(g[f[i]%x],f[i]);
for(int i=0;i<D;i++)
{
top=0;
for(int j=i;top==0||j!=i;j=(j+now)%x) stk[++top]=j;
for(int j=1;j<=top;j++) stk[j+top]=stk[j];
top<<=1;
for(int j=2;j<=top;j++)
getmin(g[stk[j]],g[stk[j-1]]+now);
}
memmove(f,g,x<<3);
now=x;
}
void solve(int x,int d,int m)
{
trans(x);
if(d<0) return ;
int D=gcd(x,d);
for(int i=0;i<D;i++)
{
top=0;l=1;r=0;
for(int j=i;top==0||j!=i;j=(j+d)%x) stk[++top]=j;
for(int j=1;j<=top;j++) stk[j+top]=stk[j];
top<<=1;
for(int j=1;j<=top;j++)
{
while(l<=r&&j-q[l]>=m) ++l;
if(l<=r) getmin(f[stk[j]],f[stk[q[l]]]+(j-q[l])*d+x);
while(l<=r&&f[stk[q[r]]]+(j-q[r])*d>f[stk[j]]) --r;
q[++r]=j;
}
}
}
int main()
{
read(z);
while(z--)
{
read(n);read(w);scanf("%s",s);
ans=tot=k=0;memset(f,0x3f,n<<3);
for(int i=1;i<n;i++)
{
while(k&&s[k]!=s[i]) k=nxt[k];
if(s[k]==s[i]) nxt[i+1]=++k;
else nxt[i+1]=0;
}
for(int i=nxt[n];i;i=nxt[i]) a[++tot]=n-i;
now=n;f[0]=n;a[tot+1]=0;
for(int i=1,j=1;i<=tot;i=j)
{
while(a[j+1]-a[j]==a[i+1]-a[i]) j++;
solve(a[i],a[i+1]-a[i],j-i);
}
for(int i=0;i<now;i++) if(f[i]<=w) ans+=(w-f[i])/now+1;
printf("%lld\n",ans);
}
return 0;
}
BZOJ4406 WC2016 论战捆竹竿的更多相关文章
- bzoj4406: [Wc2016]论战捆竹竿&&uoj#172. 【WC2016】论战捆竹竿
第二次在bzoj跑进前十竟然是因为在UOJ卡常致死 首先这个题其实就是一个无限背包 一般做法是同余最短路,就是bzoj2118: 墨墨的等式可以拿到30分的好成绩 背包是个卷积就分治FFT优化那么下面 ...
- luogu P4156 [WC2016]论战捆竹竿
传送门 官方题解(证明都在这) 神仙题鸭qwq 转化模型,发现这题本质就是一个集合,每次可以加上集合里的数,问可以拼出多少不同的数 首先暴力需要膜意义下的最短路,例题戳这 然后这个暴力可以优化成N^2 ...
- Luogu4156 WC2016 论战捆竹竿 KMP、同余类最短路、背包、单调队列
传送门 豪华升级版同余类最短路-- 官方题解 主要写几个小trick: \(1.O(nm)\)实现同余类最短路: 设某一条边长度为\(x\),那么我们选择一个点,在同余类上不断跳\(x\),可以形成一 ...
- 「WC2016」论战捆竹竿
「WC2016」论战捆竹竿 前置知识 参考资料:<论战捆竹竿解题报告-王鉴浩>,<字符串算法选讲-金策>. Border&Period 若前缀 \(pre(s,x)\ ...
- UOJ#172. 【WC2016】论战捆竹竿 字符串 KMP 动态规划 单调队列 背包
原文链接https://www.cnblogs.com/zhouzhendong/p/UOJ172.html 题解 首先,这个问题显然是个背包问题. 然后,可以证明:一个字符串的 border 长度可 ...
- UOJ#172. 【WC2016】论战捆竹竿
传送门 首先这个题目显然就是先求出所有的 \(border\),问题转化成一个可行性背包的问题 一个方法就是同余类最短路,裸跑 \(30\) 分,加优化 \(50\) 分 首先有个性质 \(borde ...
- 【WC2016】论战捆竹竿
已经快三周了啊--终于把挖的坑填了-- 首先显然是把除了自身的所有border拿出来,即做 \(\left\{ n - b_1, n - b_2, \dots, n - b_k, n \right\} ...
- 【LuoguP4156】论战捆竹竿
题目链接 题意简述 你有一个长度为 n 的字符串 , 将它复制任意次 , 复制出的串的前缀可以与之前的串的后缀重叠在一起 , 问最后总共可能的长度数目 , 长度不能超过 \(w\) 多组数据. \(n ...
- bzoj AC倒序
Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...
随机推荐
- SAS学习笔记51 SAS数据集
结构 SAS数据集是关系型的,包含两个部分:描述部分(变量)和数据部分(观察值) 形式 SAS系统中共有两种类型的数据集: 1.SAS 数据文件(SAS datafiles) 2.SAS 数据视窗(S ...
- linux命令行删除N天前的数据的命令
命令: find . -mtime +N -type f -name "*.log.*" -exec rm -f {} \; 简单解释: find .查询 ; -mtime 规 ...
- javascript基本类型和对象
JS 中分为七种内置类型,七种内置类型又分为两大类型:基本类型和对象(Object). 基本类型 null undefined boolean number string symbol 其中 JS 的 ...
- axios配置及使用(发起请求时带上token)
1.安装 利用npm安装 npm install axios --save 2.引入即可使用 import axios from 'axios' 3.目录 4.各个文件设置: (1)env.js ex ...
- FICO-清帐函数
转载:https://www.cnblogs.com/caizjian/p/8067071.html https://blog.csdn.net/sapliumeng/article/details/ ...
- 通过DB13备份SystemDB
配置systemdb capital user name:SYSTEM save -back Save 现在可以通过DB13备份SystemDB Done. Congratulations!
- How to change SAPABAP1 schema password In HANA
Symptom How to change SAPABAP1 schema password Environment HANA 1.x HANA 2.x Resolution Shutdown the ...
- C#-DBHelper
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...
- 缓存数据库memcache、redis原理对比
一.问题: 数据库表数据量极大(千万条),要求让服务器更加快速地响应用户的需求. 二.解决方案: 1.通过高速服务器Cache缓存数据库数据 2.内存数据库 (这里 ...
- cdh的web管理界面503
503 Service Unavailable No server is available to handle this request. 重启 agent 以及 server