【YCOJ 3805】竞选

又一次到了竞选班长的时间。
现在土豆的班级共有 2 名候选者小A和小B。每个同学都已经想好了自己要投给谁。
土豆第一次当班主任,希望搞点新花样,所以他会将所有同学依次编号为 1\sim N1N,然后在所有 1≤L≤R≤N1LRN 的数对 (L,R)(L,R) 中随机选择一个,然后根据编号 L\sim RLR 的同学的投票情况来决定谁当班长。
然而,土豆深知这种方式的随机性。因此,如果小A和小B票数之差的绝对值不超过 KK,那么就视作平局,土豆的班级将会有两个班长;否则就让票数较高的同学当班长。
小A担心落选,因此准备收买一些同学,即使得本来想投给小B的同学转而投给自己,使得要么平局要么自己获胜。
已知收买编号为 ii 的同学的花费为 2^i2i,请问小A的最少花费是多少?由于答案可能很大,你只需输出答案对 10^9+7109+7 取模的结果。

Input

第一行两个正整数 NN 和 KK。
第二行一个长度为 NN 的字符串,第 ii 个字符若为 \texttt{A}A 表示编号为 ii 的同学想投给小A;否则必定为 \texttt{B}B 表示想投给小B。

Output

一个数表示答案。

Sample Input

#1
4 0
BAAB

#2
4 1
BAAB

Sample Output

#1
18

#2
0

Hint

20\%20% 的数据:N ≤ 20N20;
另外 20\%20% 的数据:N≤100N100;
100\%100% 的数据:N ≤ 10^6, 0≤K ≤NN106,0KN。

 

题解:神奇算法从来不死,玄学%%%

#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
typedef long long ll;
using namespace std;
const int N=1000003;
const int mod=1000000007;
int ans,n,k,a[N],tot;
char s[N];
int main(){
    
    scanf("%d %d",&n,&k);
    a[0]=1; 
    for(int i=1;i<=n;i++) 
        a[i]=(a[i-1]<<1)%mod;//cout<<a[i]<<endl;
    scanf("%s",s+1);
    for(int i=n;i>=1;i--){
        if(s[i]=='B'){
            //cout<<i<<tot<<ans<<endl;
            ++tot;
            if(tot>k){
                ans=(ans+a[i])%mod;
                tot--;
            }
            else continue;
        }
        tot=max(0,tot-1);
    }
    printf("%d\n",ans%mod);
    return 0;
}

 

posted @ 2019-10-29 23:18  #Cookies#  阅读(324)  评论(0编辑  收藏  举报