Codeforces Round #619 (Div. 2) C. Ayoub's function

比赛时找规律发现以0为起点的子串且包含1的数量=以其后面最近的1为起点的子串数量 且m=1时令k=(n+1)/2 (/为整除)答案为 k*(n+1-k)

但没想到正难则反,换言之相对于不考虑包含1的子串的数量($frac{n(n+1)}{2}$)减少了该0所在位置至其后面距离他最近的1的距离

而m个1可以n-m个0分割成m+1段 直观感觉尽量把0均分

严格证明:因为$frac{x(x+1)}{2}$是上凹函数,由琴生不等式有$fleft ( frac{x1+x2+...+xn}{n} ight )leq frac{f(x1)+f(x2)+...+f(xn))}{n}$

移项得$nfleft ( frac{x1+x2+...+xn}{n} ight )leq f(x1)+f(x2)+...+f(xn)$ 故尽量将0分割均匀

#include<bits/stdc++.h>
#define ll  long long
using namespace std;
//const int N=e+5;

int main(){
    int T;
    ios::sync_with_stdio(false);cin.tie(0);
    cin>>T;
    while(T--){
        int n,m;
        cin>>n>>m;
        int k1=(n-m)/(m+1),k2=(n-m)%(m+1);
        cout<<1ll*n*(n+1)/2-1ll*(m+1)*k1*(k1+1)/2-1ll*k2*(k1+1)<<endl;//必须每项都先乘1ll
  }
    return 0;
}
原文地址:https://www.cnblogs.com/wyh447154317/p/12307633.html