#172. 【WC2016】论战捆竹竿

这是一个美好的下午,小 W 和小 C 在竹林里切磋捆竹竿的技艺。

竹林里有无数根完全一样的短竹子,每一根竹子由 nn 节组成。

这些竹子比较特别,每一节都被染上了颜色。可能的颜色一共 2626 种,分别用小写英文字母 a 到 z 表示。也就是说,如果把竹子的底端到顶端的颜色按顺序写出来可以排成一个由小写英文字母组成的字符串。

小 W 和小 C 都是捆竹竿的高手,他们知道怎样才能把零散的短竹子捆成一整根长竹竿。初始时你拿着一根短竹子作为当前的竹竿。每次你可以选择一根短竹子,短竹子底端若干节(可以是 00 节)与竹竿的最上面若干节对应地一节一节捆起来,而短竹子前面剩下的节伸出去,这样就得到了一根更长的竹竿。注意,竹子的底端是靠近根部的那一端,不可以颠倒。

小 W 对竹竿的审美要求很高,他捆竹竿时有一个癖好:如果两根竹子的某两节被捆在了一起,那么它们的颜色必须相同。

我们假设一根短竹子从底端到顶端每节的颜色为 aba。

那么两根竹子可以首尾捆在一起,可以得到一根颜色为 abaaba 的竹竿;也可以将第一根顶端的一节 a 与第二根底端的一节 a 捆在一起,得到一根颜色为 ababa 的竹竿;还可以直接将每一节都对应起来,捆成一根颜色为 aba 的竹竿。

假设我们在颜色为 ababa 的竹竿顶端再捆一根竹子,则可以捆成 ababaaba,abababa 和 ababa 三种不同的情况。

但是小 C 在这个问题上有不同的看法,他认为小 W 捆不出很多种长度不同的竹竿。小 W 非常不服,于是他找到了你——现在请你求出在竹竿长度不超过 ww 的情况下,小 W 可以捆出多少种长度不同的竹竿。其中,竹竿的长度指从底端到顶端的竹子的节的个数。

注意:如果 w<nw<n,则没有合法的长度,此时答案为 00。

输入格式

第一行包含 11 个正整数 TT,为数据组数。

每组数据的第一行包含 22 个正整数 nn 和 ww,表示短竹子的长度和竹竿的长度上限。

每组数据的第二行包含一个长度为 nn 的字符串,该字符串仅由小写英文字母构成,表示短竹子从底端到顶端每节的颜色。

输出格式

输出共 TT 行,每行包含一个整数表示捆成竹竿的不同长度种数。

样例一

input

1
4 11
bbab

output

5

explanation

可以捆成长度不超过 1111 的竹竿有 66 种不同的情况:

  1. bbab
  2. bbabbab
  3. bbabbbab
  4. bbabbabbab
  5. bbabbabbbab
  6. bbabbbabbab

后两种竹竿长度相同,因此不同长度的竹竿共有 55 种。长度分别为:4,7,8,10,114,7,8,10,11。

样例二

input

2
44 1000
baaaaaabaabbaaabbbbabbbaaabbbababaaabaaabaaa
41 1000
abaabbabaaabaabbbbbbbbbbbababbbbaaabaabbb

output

195
24

样例三

见样例数据下载。

限制与约定

对于所有的测试数据,保证所有的字符串均由小写字母构成,保证 T=5T=5。

各测试点满足以下约定:

测试点编号 nn ww 约束
1 ≤10≤10 ≤10≤10 ss 仅包含字母 a 和 b
2 ≤20≤20 ≤20≤20
3 ≤100≤100 ≤1018≤1018
4
5 ≤103≤103
6
7 ≤5×104≤5×104 ≤105≤105
8
9
10
11 ≤7×104≤7×104 ≤1018≤1018
12
13 ≤105≤105
14
15
16
17 ≤5×105≤5×105
18
19
20

时间限制:1s1s

空间限制:256MB

/*可能是因为string导致7~10爆了空间
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#define maxn 500010
using namespace std;
int n,w,nxt[maxn],ans;
string s;
bool vis[maxn];
void getnxt(){int i=0,j=-1;nxt[0]=-1;while(i!=n){if(s[i]==s[j]||j==-1)nxt[++i]=++j;else j=nxt[j];}
}
void dfs(string c,int len){if(!vis[len]&&len<=w)vis[len]=1,ans++;else return;int j=nxt[n];while(j){dfs(c+s.substr(j,n-j),len+(n-j));j=nxt[j];}dfs(c+s,len+n);
}
int main(){int T;scanf("%d",&T);while(T--){memset(vis,0,sizeof(vis));ans=0;scanf("%d%d",&n,&w);cin>>s;getnxt();dfs(s,n);printf("%d\n",ans);}
}

10分 kmp暴力

#include<cstdio>
#include<cstring>
#include<algorithm>
#define LL long long
using namespace std;
inline int read()
{int t=1,sum=0;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-') t=-1;ch=getchar();}while(ch>='0'&&ch<='9')sum=sum*10+ch-'0',ch=getchar();return t*sum;
}
const int Max=1e6+10;
const LL inf=1e18;
int nxt[Max],q[Max],Q[Max],len[Max],n,nm;
LL f[Max],w[Max],W; char s[Max];
void get_nxt()
{int i,j;for(nxt[1]=j=0,i=2;i<=n;i++){while(j&&s[j+1]!=s[i]) j=nxt[j];nxt[i]=s[j+1]==s[i]?++j:j;}
}
int gcd(int a,int b)
{return !b?a:gcd(b,a%b);
}
void change(int x)
{int d=gcd(x,nm),i,j,tot; static LL pre[Max];for(i=0;i<nm;i++) pre[i]=f[i];for(i=0;i<x;i++) f[i]=inf;for(i=0;i<nm;i++) if(pre[i]!=inf)j=pre[i]%x,f[j]=min(f[j],pre[i]);for(i=0;i<d;i++){tot=0; j=i;while(true){q[++tot]=j;j=(j+nm)%x;if(j==i) break;}for(j=1;j<=tot;j++) q[tot+j]=q[j];tot<<=1;for(j=2;j<=tot;j++) f[q[j]]=min(f[q[j]],f[q[j-1]]+nm);}nm=x;
}
void update(int a0,int d,int num)
{int D=gcd(d,a0),i,j,k,tot,N,l,r; static LL w[Max],mi; change(a0);for(i=0;i<D;i++){tot=0; j=i;while(true){q[++tot]=j;j=(j+d)%a0;if(j==i) break;}for(mi=inf,j=1;j<=tot;j++) if(f[q[j]]<mi) mi=f[q[j]],k=j;if(mi==inf) continue;else N=0;for(j=k;j<=tot;j++) Q[++N]=q[j];for(j=1;j<k;j++) Q[++N]=q[j];q[1]=l=r=1; w[1]=f[Q[1]]-d;for(j=2;j<=N;j++){if(q[l]+num<=j) l++;if(l<=r) f[Q[j]]=min(f[Q[j]],w[l]+1LL*j*d+a0);while(l<=r&&w[r]>=f[Q[j]]-1LL*j*d) r--;q[++r]=j; w[r]=f[Q[j]]-1LL*j*d;}}
}
int main()
{int T=read(),i,j,k; LL ans;while(T--){n=read(); scanf("%lld",&W); W-=n;scanf("%s",s+1); get_nxt();if(W<0){puts("0");continue;}for(j=0,i=nxt[n];i;i=nxt[i]) len[++j]=n-i;for(i=1;i<=(j>>1);i++) swap(len[i],len[j-i+1]);for(f[0]=0,i=1;i<n;i++) f[i]=inf;nm=n;for(i=1;i<=j;i=k){if(i==j) {update(len[i],1,1);break;}for(k=i+1;k<=j&&len[i]-len[i+1]==len[k-1]-len[k];k++);update(len[k-1],len[i]-len[i+1],k-i);}for(ans=i=0;i<nm;i++)if(f[i]!=inf&&f[i]<=W)ans+=(W-f[i])/nm+1;printf("%lld\n",ans);}return 0;
}

100分 完全不明白

转载于:https://www.cnblogs.com/thmyl/p/8098574.html

uoj #172. 【WC2016】论战捆竹竿相关推荐

  1. [WC2016] 论战捆竹竿 [学习笔记] 同余最短路

    本来想做字符串的题,结果发现了这个坑把他填上. 什么是同余最短路? 同余最短路是解决这样一类问题:给你若干个数 a [ i ] a[i] a[i] ,每个数可以选无限次加起来,问最后的和有多少种在 m ...

  2. Luogu4156 WC2016 论战捆竹竿 KMP、同余类最短路、背包、单调队列

    传送门 豪华升级版同余类最短路-- 官方题解 主要写几个小trick: \(1.O(nm)\)实现同余类最短路: 设某一条边长度为\(x\),那么我们选择一个点,在同余类上不断跳\(x\),可以形成一 ...

  3. BZOJ4406 WC2016 论战捆竹竿

    Problem BZOJ Solution 显然是一个同余系最短路问题,转移方案就是所有|S|-border的长度,有 \(O(n)\) 种,暴力跑dijkstra的复杂度为 \(O(n^2\log ...

  4. UOJ#172. 【WC2016】论战捆竹竿

    传送门 首先这个题目显然就是先求出所有的 b o r d e r border border,问题转化成一个可行性背包的问题 一个方法就是同余类最短路,裸跑 30 30 30 分,加优化 50 50 ...

  5. UOJ#172. 【WC2016】论战捆竹竿 字符串 KMP 动态规划 单调队列 背包

    原文链接https://www.cnblogs.com/zhouzhendong/p/UOJ172.html 题解 首先,这个问题显然是个背包问题. 然后,可以证明:一个字符串的 border 长度可 ...

  6. 【WC2016】论战捆竹竿

    已经快三周了啊--终于把坑填了-- 首先显然是把除了自身的所有border拿出来,即做 \(\left\{ n - b_1, n - b_2, \dots, n - b_k, n \right\}\) ...

  7. [国家集训队]墨墨的等式

    想要写论战捆竹竿,看了题解学了一点姿势,发现了一些奇怪的东西(我以前这道题写的太菜了) 首先这道题可以转化为模 \(A_i\) 最小值 \(m\) 意义下的最短路,求出每个模 \(m\) 意义下的值最 ...

  8. WC酱油记——博客一个月没更新留念

    不知不觉一月就这么过去了,估计二月也会很快的谜之消失吧.. 博客一直也没有更新,CF的题也是坑着一坨,考试考的我身败名裂然后还要去参加WC被虐... 总之一下就回忆一下我的WC日常吧..但是因为我是隔 ...

  9. 习学ix53 [字符串算法] 笔记2

    我已经已关机 结论:p 是 S 的周期,当且仅当 ∣S∣−p|S|-p∣S∣−p 是 S 的 Border. 弱周期引理(Weak Periodicity Lemma):若 p,qp,qp,q 是串 ...

  10. 【QQ技术】群文件报毒怎样下载?~ 变相绕过QQ复杂检验过程

    刚才又人问我,要是群文件被鉴定为病毒那怎么下载? 我简单说一下吧: 其实qq客户端过滤比较严的,而web段却还是老一套,很多人说出现这个情况其实是腾讯已经把他库里面的文件删了,其实不然 如果源删了,那 ...

最新文章

  1. 中国在科技领域崛起 美国人的保护主义蠢蠢欲动
  2. 史上最简单的SpringCloud教程 | 第九篇: 服务链路追踪(Spring Cloud Sleuth)
  3. 一个奇葩的网络问题,把技术砖家搞蒙了
  4. 如果用户希望将一台计算机,计算机网络试卷(有答案版)
  5. 使用java 遍历文件夹
  6. 【写作技巧】计算机应用技术毕业论文范文
  7. Makefile,Shell command,Shell Language 之间的联系
  8. SVG 图标和sketch 模版免费网站
  9. 金橙子激光打标机的二次开发(C#)
  10. STM32——PS2遥控手柄
  11. 软件测试真的是吃青春饭的吗?有哪些建议可以给刚入职的测试员?(全是干货)
  12. 数据库与Java语言之间的鹊桥——JDBC
  13. 大话设计模式 第二十三章 命令模式 考羊肉串
  14. Qt Jambi 4.8 快速入门
  15. 设计师常用的7款界面设计工具!
  16. python读取身份证中的生日信息
  17. 开唐贡献榜(凌烟阁二十四功臣)
  18. 字符编码的故事(转)
  19. ExecutorService 使用invokeAll提交多个任务并等待结果
  20. 电子科技大学《图论及其应用》复习总结---第二章 树

热门文章

  1. 红色警戒2修改器原理百科(二)
  2. AHU计科(伪)新生指南
  3. jupyter notebook 配置没问题却连接不上服务器
  4. 深度学习策略之图像预处理
  5. 非支配快速排序算法详解
  6. 深入解析锂电池保护电路工作原理
  7. 百度云c++语言模拟器,C++语言基础教程
  8. 舍得酒业前三季营收净利双增背后 低档酒提速拖累Q3毛利率
  9. HCNE之RIP协议总结
  10. Word2003入门动画教程88:使用Word公式编辑器