[树状数组][DP]JZOJ 4738 神在夏至祭降下了神谕

Description

 

Input

Output

 

Sample Input

4 1
0 0 1 1

Sample Output

5
 

Data Constraint

 

Hint

分析

状态转移方程显然:

f[i]=∑f[j] (|s[i]-s[j-1]|≤k)

发现如果i向后移一位,那么整个区间整体要不+1要不-1

那么可以直接减掉k作为树状数组中的下标,用树状数组求出符合的和即可

#include <iostream>
#include <cstdio>
#define lowbit(x) x&-x
using namespace std;
typedef long long ll;
const int N=2e5;
const ll P=1e9+7;
ll c[2*N+1],s[N],f[N];
int n,k;

void Add(int x,ll dat) {
    for (int i=x+N;i<=2*N;i+=lowbit(i)) (c[i]+=dat)%=P;
}

ll Get_Sum(int x) {
    ll ans=0;
    for (int i=x+N;i;i-=lowbit(i)) (ans+=c[i])%=P;
    return ans;
}

int main() {
    scanf("%d%d",&n,&k);
    for (int i=1;i<=n;i++) {
        int a;
        scanf("%d",&a);
        s[i]=s[i-1]+(!a?1:-1);
    }
    Add(0,1);
    for (int i=1;i<=n;i++)
    f[i]=(Get_Sum(s[i]+k)-Get_Sum(s[i]-k-1)+P)%P,Add(s[i],f[i]);
    printf("%lld",f[n]);
}
View Code

 

posted @ 2018-08-21 20:12  Vagari  阅读(195)  评论(0编辑  收藏  举报