题目

一个长为\(N\)的串\(S\),\(M\)询问区间\([l,r]\)不同的子串个数,字符集为$ C $

\(N ,M \le 10^5 \ , \ C \le 10\)

题解

  • 这题非常套路。。。

  • part 1

  • 设\(dp_{i,j}\)为考虑i,字符j结尾的子串个数,考虑\(S_i=c\)

    \[\begin{align}
    &dp_{i,j} = dp_{i,j}\\
    &dp_{i,c} = \sum_{j} dp_{i-1,j} + 1
    \end{align}
    \]

  • part 2

  • 设一个大小\(C+1\)的矩阵,写出转移矩阵

    \[A_i = \begin{pmatrix}
    1 & 0 & 0 & 0\\
    0 & 1 & 0 & 0\\
    1 & 1 & 1 & 1\\
    0 & 0 & 0 & 1\\
    \end{pmatrix}
    \]

    它的逆矩阵

    \[B_i = \begin{pmatrix}
    1 & 0 & 0 & 0\\
    0 & 1 & 0 & 0\\
    -1 & -1 & -1 & -1\\
    0 & 0 & 0 & 1\\
    \end{pmatrix}
    \]

    只需要预处理出矩阵的前缀即可

  • part 3

    左乘一个A相当于某一行变为所有行的和,可以维护一列的和

    右乘一个B相当于其它列减去某一列,可以维护整体减法标记

    统计答案也可以直接利用维护的东西,具体见代码

    时间复杂度$ O((N+M)C) $

#include<bits/stdc++.h>
using namespace std;
const int N=500010,mod=1e9+7;
int n,m,f1[N][11],f2[N][11]; char s[N],ps[1000000],*pp=ps;
void flush(){fwrite(ps,1,pp-ps,stdout);pp=ps;}
void push(char x){if(pp==ps+1000000)flush();*pp++=x;}
void write(int x){
static int sta[20],top;
if(!x){push('0');push('\n');return;}
while(x)sta[++top]=x%10,x/=10;
while(top)push(sta[top--]^'0');
push('\n');
} void inc(int&x,int y){x+=y;if(x>=mod)x-=mod;}
void dec(int&x,int y){x-=y;if(x<0)x+=mod;} struct Mat{
int c[11][11],s[11],d[11],D;
void init(){for(int i=0;i<11;++i)c[i][i]=s[i]=1;}
void plus(int I){
for(int i=0;i<11;++i){
int t=c[I][i];c[I][i]=s[i];
s[i]=(2*s[i]%mod-t+mod)%mod;
}
}
void minus(int I){
for(int i=0;i<11;++i){
int t=d[i];d[i]=c[i][I];
c[i][I]=(2*d[i]%mod-t+mod)%mod;
}
}
void print(int typ){
for(int i=0;i<11;++i,puts(""))
for(int j=0;j<11;++j){
int t=typ?(c[i][j]-d[i]+mod)%mod:c[i][j];
if(mod-t<t)t=t-mod;
printf("% 2d ",t);
}
puts("\n");
if(!typ)for(int i=0;i<11;++i)printf("%d ",s[i]);
puts("\n");
}
}A,B; int main(){
freopen("sequence.in","r",stdin);
freopen("sequence.out","w",stdout);
scanf("%s%d",s+1,&m);n=strlen(s+1);
A.init(),B.init();f2[0][10]=1;
for(int i=1;i<=n;++i){
A.plus(s[i]-'a');
B.minus(s[i]-'a');
for(int j=0;j<11;++j){
f1[i][j]=A.s[j];
f2[i][j]=(B.c[j][10]-B.d[j]+mod)%mod;
}
}
for(int i=1,l,r,ans;i<=m;++i){
scanf("%d%d",&l,&r);
ans=0;for(int j=0;j<11;++j)inc(ans,1ll*f1[r][j]*f2[l-1][j]%mod);
if(!ans)ans=mod-1;else ans--;write(ans);
}
return flush(),0;
}

【JZOJ6216】【20190614】序列计数的更多相关文章

  1. [Sdoi2017]序列计数 [矩阵快速幂]

    [Sdoi2017]序列计数 题意:长为\(n \le 10^9\)由不超过\(m \le 2 \cdot 10^7\)的正整数构成的和为\(t\le 100\)的倍数且至少有一个质数的序列个数 总- ...

  2. BZOJ_4818_[Sdoi2017]序列计数_矩阵乘法

    BZOJ_4818_[Sdoi2017]序列计数_矩阵乘法 Description Alice想要得到一个长度为n的序列,序列中的数都是不超过m的正整数,而且这n个数的和是p的倍数.Alice还希望 ...

  3. HDU 6348 序列计数 (树状数组 + DP)

    序列计数 Time Limit: 4500/4000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)Total Subm ...

  4. luogu3702-[SDOI2017]序列计数

    Description Alice想要得到一个长度为nn的序列,序列中的数都是不超过mm的正整数,而且这nn个数的和是pp的倍数. Alice还希望,这nn个数中,至少有一个数是质数. Alice想知 ...

  5. BZOJ4818 序列计数

    4818: [Sdoi2017]序列计数 Time Limit: 30 Sec  Memory Limit: 128 MB Description Alice想要得到一个长度为n的序列,序列中的数都是 ...

  6. 【BZOJ 4818】 4818: [Sdoi2017]序列计数 (矩阵乘法、容斥计数)

    4818: [Sdoi2017]序列计数 Time Limit: 30 Sec  Memory Limit: 128 MBSubmit: 560  Solved: 359 Description Al ...

  7. P3702 [SDOI2017]序列计数

    P3702 [SDOI2017]序列计数 链接 分析: 首先可以容斥掉,用总的减去一个质数也没有的. 然后可以dp了,f[i][j]表示到第i个数,和在模p下是j的方案数,矩阵快速幂即可. 另一种方法 ...

  8. 【BZOJ4818】[Sdoi2017]序列计数 DP+矩阵乘法

    [BZOJ4818][Sdoi2017]序列计数 Description Alice想要得到一个长度为n的序列,序列中的数都是不超过m的正整数,而且这n个数的和是p的倍数.Alice还希望 ,这n个数 ...

  9. BZOJ4818 LOJ2002 SDOI2017 序列计数 【矩阵快速幂优化DP】*

    BZOJ4818 LOJ2002 SDOI2017 序列计数 Description Alice想要得到一个长度为n的序列,序列中的数都是不超过m的正整数,而且这n个数的和是p的倍数. Alice还希 ...

  10. 【BZOJ4818】序列计数(动态规划,生成函数)

    [BZOJ4818]序列计数(生成函数) 题面 BZOJ 题解 显然是求一个多项式的若干次方,并且是循环卷积 或者说他是一个\(dp\)也没有问题 发现项数很少,直接暴力乘就行了(\(FFT\)可能还 ...

随机推荐

  1. docker save load export import的区别

    export export命令用于持久化容器(不是镜像).所以,我们就需要通过以下方法得到容器ID: sudo docker ps -a 接着执行导出: sudo docker export < ...

  2. 一个简单实现的string类

    为了复习c++知识,简单的实现一个string类,类名为CMyString 环境说明:windows 7 64位 和 CentOS Linux release 7.6.1810 (Core) 开发工具 ...

  3. day 07 作业

    猜年龄游戏 ''' 给定年龄,用户可以猜三次年龄 年龄猜对,让用户选择两次奖励 用户选择两次奖励后可以退出 ''' age_count = 0 age = 20 prize_dict = { '0': ...

  4. 腾讯微服务框架Tars的初体验

    最近研究了一下腾讯的微服务体系开发框架. 官方的搭建过程:https://github.com/TarsCloud/Tars/blob/master/Install.zh.md 自己填的坑: 不得不说 ...

  5. Linux无法被远程登录;用户的关机, 重启,注销,新增用户,删除用户

    不能使用xshell连接到我的Linux服务器 通过再windows的cmd中ping了我的Linux地址,发现网络不通. 查看百度发现是因为网络没有选桥接模式,然后选完桥接模式告诉我: 然后发现没有 ...

  6. 如何预防SQL注入?预编译机制

    1.预编译机制(一次编译多次执行,防止sql注入) 2.预编译机制

  7. node基础学习——http基础知识-02-http响应数据流

    <一> 发送服务器端响应流 在createServer()方法的参数值回调函数或服务器对象的request事件函数中的第二个参数值为一个http.ServerResponse对象,可以利用 ...

  8. anyproxy学习1-windows平台安装和抓手机app上https请求

    前言 做接口测试肯定离不开抓包,目前比较流行的抓包工具是fiddler和charles,相信并不陌生.这里介绍一个阿里公司研发的一个抓包神器,只需打开web页面,就能抓到手机app上的http和htt ...

  9. 微信小程序~用户转发 onShareAppMessage

    只有定义了此事件处理函数,右上角菜单才会显示“转发”按钮,在用户点击转发按钮的时候会调用,此事件需要return一个Object,包含title和path两个字段,用于自定义转发内容 代码使用onSh ...

  10. 编程小白入门分享二:IntelliJ IDEA的入门操作小知识

    idea简介 IDEA 全称 IntelliJ IDEA,是java编程语言开发的集成环境.IntelliJ在业界被公认为最好的java开发工具之一,尤其在智能代码助手.代码自动提示.重构.J2EE支 ...