acwing 4078. 01串
作者:互联网
给定一个整数 k
。
现在,我们可以对 01
字符串进行如下操作:
选择其中恰好 k
个连续的 1,将它们都变为 0
。
如果一个 01
字符串可以通过若干次上述操作,变为一个全 0
字符串,那么就称这个字符串很优秀。
本题共需要回答 T
组询问,每组询问给定两个整数 l,r,并请你计算长度在 [l,r] 范围内的所有 01
字符串中优秀字符串的数量。
输入格式
第一行包含两个整数 T
和 k
。
接下来 T
行,每行包含两个整数 l,r
。
输出格式
共 T
行,第 i 行输出第 i 组询问的答案对 109+7
取模后的结果。
数据范围
前三个测试点满足 1≤T,k≤10
。
所有测试点满足 1≤T,k≤105,1≤l≤r≤105
。
输入样例:
3 2
1 3
2 3
4 4
输出样例:
6
5
5
presum[i]:表示长度为i的01串优秀字符串的数量
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 1e5 + 10, mod = 1e9 + 7;
typedef long long LL;
LL presum[N];
int main(){
int T, k;
cin >> T >> k;
presum[0] = 1;
for(int i = 1; i < N; i ++){
if(i < k)presum[i] = presum[i - 1];//只有全都为0这一种可能
else presum[i] = (presum[i - k] + presum[i - 1]) % mod; //长度为i - k长度的字串长度 + i-1长度优秀字符串的数量
//第二项不用说 第一项:样例有一个4 4的 一共有5种可能 0000 0011 0110 1100 1111 其中0000和1111就是通过persum[2]得出
//长度为2的时候一共有00 11两种可能 所以长度为4的时候不仅要计算0011 0110 1100这三项, 还要计算0000 1111这一部分, 这一部分的数量又完全和presum[2]的数量相等, 所以presum[i] = presum[i - k] + presum[i - 1]
}
presum[0] = 0;
for(int i = 1; i < N; i ++){
presum[i] = (presum[i] + presum[i - 1]) % mod;
}
while(T --){
int l, r;
cin >> l >> r;
cout << ((presum[r] - presum[l - 1]) % mod + mod) % mod << endl;
}
}
标签:01,4078,int,字符串,长度,presum,include,acwing 来源: https://www.cnblogs.com/jw-zhao/p/15582522.html