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 ...
随机推荐
- HTTP无状态协议理解
TTP协议是无状态协议. 无状态是指协议对于事务处理没有记忆能力.缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大.另一方面,在服务器不需要先前信息时它的应 ...
- Visual Studio中找不到.Net Core SDK
在win 7 64位上安装了.Net Core 2.1 x86 SDK后,又卸载重新安装了.Net Core 3/2 x64 SDK.结果在VS中新建项目时没有.Net Core 3.1 SDK. 在 ...
- 我对xss以及sql的理解
我对xss以及sql的理解 本文作者:情殇(查看作者所有博文) 作者邮箱:3135117931@qq.com 发布时间: Fri, 12 Jul 2019 19:16:00 +0800 Xss和sql ...
- JavaScript CryptoJS库 加密与解密
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- ArcCatalog连接数据库报错
ArcCatalog连接数据库报错: Failed to connect to database. Cannot connect to database because the database cl ...
- PCI总线学习
PCI总线概述: 因为不实际操作了,所以就写一些方法论上的东西,纪念一下. PCI总线有三个非常显著的优点: 1. 在计算机和外设传输数据时具有更好的性能. 2. 能够尽量独立于具体的平台. 3. 可 ...
- ceph集群部署(基于jewel版)
环境 两个节点:ceph1.ceph2 ceph1: mon.mds.osd.0.osd.1 ceph2: osd.2.osd.3 网络配置: ceph1: 管理网络,eth0,10.0.0.20 存 ...
- Python基础笔记一
1. 分片的步长,默认为值1,表示为 xx[s:t:v] ----从索引s到索引t,每隔v,取对应索引位置的值 xx = 'hello,world' #从索引0-10,共11个字符 xx[2:] #从 ...
- RT-Thread--中断管理
Cortex-M CPU架构基础 寄存器简介 Cortex-M 系列 CPU 的寄存器组里有 R0\~R15 共 16 个通用寄存器组和若干特殊功能寄存器,如下图所示. 通用寄存器组里的 R13 作为 ...
- Luogu P2935 最好的地方Best Spot
Luogu P2935 最好的地方Best Spot 这道题就是一道近乎裸的Floyd,因为数据很小,所以用领接表存图就可以了. #include<bits/stdc++.h> #defi ...