都是中文题不需要翻译,话说,我居然sb的在a题看错题目错了3发
ABD签到题,D题贪心思维,没啥好说的
我觉得这题是我卡了最久的题,数学不好推不出来,然后打了个表发现的,官方题解里有证明为什么a=192*q+1,q是自然数。知道这个之后就很好做了,我们就可以求出在r范围内有多少符合的数,和l-1范围内有多少符合的数做差就可以了。像对于x,我们先求出它范围里有多少个192的倍数,就是q=x/192,然后a是192*q+1,如果x刚好是q的倍数,那么q就去掉一个1个,然后是求∑a,而范围内192的倍数有q个,∑a就是192*(1+2+3+..+q)+q+1

1 #include<cstdio> 2 #include<algorithm> 3 using namespace std; 4 typedef long long ll; 5 ll solve(int x) 6 { 7 if(!x) 8 return 0; 9 ll q=x/192; 10 if(x%192==0) 11 q--; 12 return 192ll*q*(1+q)/2+q+1;//+1是对1这个情况特判 13 } 14 int main() 15 { 16 int t,l,r; 17 scanf("%d",&t); 18 while(t--) 19 { 20 scanf("%d%d",&l,&r); 21 printf("%lld ",solve(r)-solve(l-1)); 22 } 23 return 0; 24 }
一开始感觉没啥思路,想要贪心但是很容易举出反例,但模拟了一下之后有了个类似尺取的思路。因为尺取有个左端点的调整,但我不确定这个左端点该如何调整,所以我改成了枚举左端点,然后去模拟。
具体思路就是,先把字符串分成连续的01子串,比如0001110011就可以分成4个字串,然后相应的权值就是它们的长度,v[0]=3,v[1]=3,v[2]=2,v[3]=2,这样的话,每个子串的下一个子串就是和它不同的需要翻转,而下下个就是和它相同的,不需要翻转。然后就枚举一个子串v[i]作为头部,然后就模拟看最多翻转m个字符,它可以延伸的长度,详情见代码。

1 #include<cstdio> 2 #include<vector> 3 #include<algorithm> 4 using namespace std; 5 const int N=100118; 6 char s[N]; 7 vector<int> v; 8 int main() 9 { 10 int t,n,m; 11 scanf("%d",&t); 12 while(t--) 13 { 14 scanf("%d%d",&n,&m); 15 scanf("%s",s); 16 v.clear(); 17 int sum=0,ans=0,len; 18 for(int i=0;s[i]!='