这题真神。。。

首先看到这么花里胡哨的题面眉头一皱就发现这个球的大小是搞笑的不然就没法做了,有用的是最终拆出来的长度

然后对于一段长度为n有n-1个丝状物的东西,写一个DP:f[i][2]表示枚举到第i个丝状物,当前断不断

那f[i][0]=f[i-1][1] f[i][1]=f[i-1][0]+f[i-1][1]=f[i-2][1]+f[i-1][1] 最终答案是f[n-1][1],把[1]去掉就是一个斐波那契数列

设c[n]表示长度为n一共构成的方案数,c[n]=fib[n-1]

那么题意转化为给你一个序列,分成若干段,求∑fib[(∑di)-1]  di是每一段表示的数字

fib肯定是要用矩阵乘法求的了,那么相当于求∑A * (M^(∑di)-2)) =A * (∑M^(∑di)) * (M^-2) 注意这里(M^-2)不能放在前面,矩乘没有交换律

要算的就是∑M^(∑di)=∑∑M^di(分配律),我们发现di实在是太大了,假如一次都不分割可以到1000位

我们把d的每一个十进制位拆出来,∑∑M^di=∑∑M^(∑ai*mj) 其中ai表示d的从左到右第i位的数字,mj是10^j,j表示i在d中是从右往左的第j+1位

再开出来∑∑M^(∑ai*mj)=∑∑∑(M^mj)^ai,M^mj可以预处理,设为gj的话原式=∑∑∑gj^ai

整理一下,现在的做法是枚举每一个状态,枚举这个状态的每一个段,枚举这个状态的每一个位把它的贡献加上

但是状态实在是太多了!我们必须再优化

设fi表示前i个细胞已经分好了上面那坨东西的和,因为有分配律所以我们可以先把不同状态当前的和先加起来

对于转移 fi=∑fj* c(j+1,i) 其中c(j+1,i)表示j+1~i变成一个段对答案的贡献,其实就是∑gj^ai嘛

直接这样做是n^3的,但是反过来for就可以把后面那个∑消掉

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long LL;
const int maxn=;
const LL mod=1e9+; struct Matrix
{
LL mp[][];
void clear(){memset(mp,,sizeof(mp));}
void init(){clear();mp[][]=;mp[][]=;}
friend Matrix operator +(Matrix a,Matrix b)
{
Matrix c;c.clear();
for(int i=;i<=;i++)
for(int j=;j<=;j++)
c.mp[i][j]=(a.mp[i][j]+b.mp[i][j])%mod;
return c;
}
friend Matrix operator *(Matrix a,Matrix b)
{
Matrix c;c.clear();
for(int i=;i<=;i++)
for(int j=;j<=;j++)
for(int k=;k<=;k++)
c.mp[i][j]=(c.mp[i][j]+a.mp[i][k]*b.mp[k][j])%mod;
return c;
}
friend Matrix operator ^(Matrix a,int p)
{
Matrix c;c.init();
while(p!=)
{
if(p%==)c=c*a;
a=a*a;p/=;
}
return c;
}
}mi[maxn];//fib矩阵的10^k char ss[maxn];
int a[maxn];Matrix f[maxn],s;
int main()
{
mi[].mp[][]=,mi[].mp[][]=;
mi[].mp[][]=,mi[].mp[][]=;
for(int i=;i<=;i++)mi[i]=mi[i-]^; mi[].mp[][]=mod-,mi[].mp[][]=;
mi[].mp[][]=,mi[].mp[][]=;//fib逆运算 mi[].mp[][]=,mi[].mp[][]=;//A //.......init............ int n;
scanf("%d",&n);
scanf("%s",ss+);
for(int i=;i<=n;i++)a[i]=ss[i]-'';
f[].init();
for(int i=;i<=n;i++)
{
s.init();
for(int j=i-;j>=;j--)
{
s=s*(mi[i-j-]^a[j+]);
f[i]=f[i]+f[j]*s;
}
}
f[n]=mi[]*f[n]*mi[]*mi[];
printf("%lld\n",f[n].mp[][]); return ;
}

bzoj2323: [ZJOI2011]细胞的更多相关文章

  1. 【BZOJ 2323】 2323: [ZJOI2011]细胞 (DP+矩阵乘法+快速幂*)

    2323: [ZJOI2011]细胞 Description 2222年,人类在银河系外的某颗星球上发现了生命,并且携带了一个细胞回到了地球.经过反复研究,人类已经完全掌握了这类细胞的发展规律: 这种 ...

  2. [ZJOI2011]细胞——斐波那契数列+矩阵加速+dp

    Description bzoj2323 Solution 题目看起来非常复杂. 本质不同的细胞这个条件显然太啰嗦, 是否有些可以挖掘的性质? 1.发现,只要第一次分裂不同,那么互相之间一定是不同的( ...

  3. BZOJ 2323: [ZJOI2011]细胞

    嗯..csdn发得出markdown了..请移步~ 个人觉得那个帅一点 嗯 好题啊!! 矩乘+DP 蒟蒻的我一开始发现了斐波那契数列之后就不会搞了.. 那个..什么质量相同两种方案相同就是扯淡的..想 ...

  4. WC前的小计划

    写在前面的.. 要去WC了好开心的呢.. 但是之前荒废了好多时间呢.. 好吧从明天开始加紧训练,目标是:WC前bzoj300t..(现在是260呢..) 开始吧 来看看完成情况: 40/40 [201 ...

  5. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

  6. #include <NOIP2009 Junior> 细胞分裂 ——using namespace wxl;

    题目描述 Hanks 博士是 BT (Bio-Tech,生物技术) 领域的知名专家.现在,他正在为一个细胞实 验做准备工作:培养细胞样本. Hanks 博士手里现在有 N 种细胞,编号从 1~N,一个 ...

  7. NOIP2009普及组细胞分裂(数论)——yhx

    题目描述 Hanks 博士是 BT (Bio-Tech,生物技术) 领域的知名专家.现在,他正在为一个细胞实 验做准备工作:培养细胞样本. Hanks 博士手里现在有 N 种细胞,编号从 1~N,一个 ...

  8. BZOJ2229: [Zjoi2011]最小割

    题解: 真是一道神题!!! 大家还是围观JZP的题解吧(网址找不到了...) 代码: #include<cstdio> #include<cstdlib> #include&l ...

  9. 【OpenCV】基于kmeans的细胞检测方法

    问题是这样的,有一幅经过二值化处理之后的图像,我们希望统计其中细胞的个数,和不同粘连情况的细胞个数,比如,下图中有1个细胞组成连通区域的,也有2个细胞组成连通区域的,也有更多个细胞组成连通区域的,我们 ...

随机推荐

  1. set()集合基本操作

    运用频次:☆☆ set是一个无序且不重复元素集,基本操作如下: 1. 创建set集合,会自动转换成set类型 2. add():添加元素 def add(self, *args, **kwargs): ...

  2. sql中Distinct&Count的用法

    Distinct作用:消除重复的数值 1.如: select id from T1 select distinct id from T1 二者的检索效果如下: distinct可以用来修饰多列,如: ...

  3. HDU 4334 5-sum

    题目大意: 从5个集合中个选取一个数出来,使5个数相加之和为0 , 判断是否存在这种可能 因为集合数目最多200,那么200^3 = 8000000 , 那么这里很明显要把5个数拆成2个和3个计算,因 ...

  4. 洛谷P3094 [USACO13DEC]假期计划Vacation Planning

    题目描述 有N(1 <= N <= 200)个农场,用1..N编号.航空公司计划在农场间建立航线.对于任意一条航线,选择农场1..K中的农场作为枢纽(1 <= K <= 100 ...

  5. [codevs] 1699 开关灯

    题目描述 Description YYX家门前的街上有N(2<=N<=100000)盏路灯,在晚上六点之前,这些路灯全是关着的,六点之后,会有M(2<=m<=100000)个人 ...

  6. 关于Linux内核学习的一点点总结

    关于Linux内核学习的一点点总结 关键词:Linux, 操作系统,内核 博客列表 由反汇编C程序来理解计算机是如何工作的 通过分析一个简化版时间片轮转多道程序内核代码来认识操作系统中的进程调度 通过 ...

  7. 通过调用C语言的库函数与在C代码中使用内联汇编两种方式来使用同一个系统调用来分析系统调用的工作机制

    通过调用C语言的库函数与在C代码中使用内联汇编两种方式来使用同一个系统调用来分析系统调用的工作机制 前言说明 本篇为网易云课堂Linux内核分析课程的第四周作业,我将通过调用C语言的库函数与在C代码中 ...

  8. 删除字符串中的"\U0000fffc"数据 textView添加图片 以及添加后属性失效的解决

    背景:在实现textView的富文本时,如果添加一张图片后,如果直接发送textView的内容时,图片会被字符串“\U0000fffc”替换. 问题:如何删除“\U0000fffc”字符串:如何替换t ...

  9. Netty 4.0 新的特性及需要注意的地方

    Netty 4.0 新的特性及需要注意的地方 这篇文章和你一起过下Netty的主发行版本的一些显著的改变和新特性,让你在把你的应用程序转换到新版本的时候有个概念. 项目结构改变 Netty的包名从or ...

  10. AtCoder Regular Contest 091&092

    091E(构造) 题意: 给出n,a,b.你需要构造出一个长度为n的n的排列,其中最长上升子序列的长度为a,最长下降子序列的长度为b. n,a,,b<=3e5 分析: 我们可以构造出这样的数列, ...