题目链接:http://codeforces.com/problemset/problem/1301/C
思路:
纯想想了一次,发现one_cnt >= zero_cnt的时候很简单,就是(n)*(n+1)/2+ont_cnt,
但是当one_cnt<zero_cnt的时候,就有点麻烦了,虽然乱七八糟的乱写,发现zero要尽可能
的被one平分才行,但是正向写就比较麻烦。
f(s) = 至少含有1个‘1’的子串 = (n)*(n-1) - fy(只包含‘0’的子串)。
那我们就是要把fy尽可能的小,显然一段长度为x的含'0'的字段,子串数 = (x)*(x+1)/2,
所以我们应该尽可能的用'1'去平分'0'。
m个‘1’最多可以把‘0’分成m+1段,每段数量就是 cnt = zero/(one+1),剩余的zero分别分配到1个到'0'字段中,
也就是remain_zero*cnt,(n)*(n-1)/2减去只包含‘0’的子串就可以了。
1 #include <iostream> 2 #include <algorithm> 3 using namespace std; 4 5 typedef long long ll; 6 7 int main(){ 8 9 int T; 10 scanf("%d",&T); 11 for(int i = 1; i <= T; ++i){ 12 ll n,one; 13 scanf("%lld%lld",&n,&one); 14 ll zero = n - one; 15 ll cnt = zero/(one+1); 16 ll remain = zero%(one+1);//剩余'0'的数量 17 ll ans = ( n*(n+1) - cnt*(cnt+1)*(one+1) )/2 - remain*(cnt+1); 18 //printf("ans = %lld ",ans); 19 printf("%lld ",ans); 20 } 21 22 23 return 0; 24 }