比赛时找规律发现以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; }