【YCOJ 3805】竞选
又一次到了竞选班长的时间。
现在土豆的班级共有 2 名候选者小A和小B。每个同学都已经想好了自己要投给谁。
土豆第一次当班主任,希望搞点新花样,所以他会将所有同学依次编号为 1\sim N1∼N,然后在所有 1≤L≤R≤N1≤L≤R≤N 的数对 (L,R)(L,R) 中随机选择一个,然后根据编号 L\sim RL∼R 的同学的投票情况来决定谁当班长。
然而,土豆深知这种方式的随机性。因此,如果小A和小B票数之差的绝对值不超过 KK,那么就视作平局,土豆的班级将会有两个班长;否则就让票数较高的同学当班长。
小A担心落选,因此准备收买一些同学,即使得本来想投给小B的同学转而投给自己,使得要么平局要么自己获胜。
已知收买编号为 ii 的同学的花费为 2^i2i,请问小A的最少花费是多少?由于答案可能很大,你只需输出答案对 10^9+7109+7 取模的结果。
现在土豆的班级共有 2 名候选者小A和小B。每个同学都已经想好了自己要投给谁。
土豆第一次当班主任,希望搞点新花样,所以他会将所有同学依次编号为 1\sim N1∼N,然后在所有 1≤L≤R≤N1≤L≤R≤N 的数对 (L,R)(L,R) 中随机选择一个,然后根据编号 L\sim RL∼R 的同学的投票情况来决定谁当班长。
然而,土豆深知这种方式的随机性。因此,如果小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。
第二行一个长度为 NN 的字符串,第 ii 个字符若为 \texttt{A}A 表示编号为 ii 的同学想投给小A;否则必定为 \texttt{B}B 表示想投给小B。
Output
一个数表示答案。
Sample Input
#1
4 0
BAAB
#2
4 1
BAAB
4 0
BAAB
#2
4 1
BAAB
Sample Output
#1
18
#2
0
18
#2
0
Hint
20\%20% 的数据:N ≤ 20N≤20;
另外 20\%20% 的数据:N≤100N≤100;
100\%100% 的数据:N ≤ 10^6, 0≤K ≤NN≤106,0≤K≤N。
另外 20\%20% 的数据:N≤100N≤100;
100\%100% 的数据:N ≤ 10^6, 0≤K ≤NN≤106,0≤K≤N。
题解:神奇算法从来不死,玄学%%%
#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; }