Codeforces1301C. Ayoub's function

本题的收获是,要学会反向思维,正向找包含1的太多,我们就反向找,全排列-只有0的不满足题意的就是答案,一共有n-m个0,m个1,插空法,一共有m+1个地方可以插入0序列,总排列数为(n+1)*n/2,每一段0序列的数是l*(l+1)/2,我们要使答案最大,就要使l尽可能小,和上题一样的思维,要最小,就取平均数,l=floor((n-m)/(m+1)), ans = n*(n+1)/2- l*(l+1)/2*(m+1),但有可能不能平均分配,就有(n-m)%(m+1)个点分配到了l+1个点,所以ans就还要再减去(l+1)*((n-m)%(m+1))

#include<bits/stdc++.h>
using namespace std;
#define lowbit(x) ((x)&(-x))
typedef long long LL;
 
void run_case() {
    int n, m;
    cin >> n >> m;
    int k = (n-m)/(m+1);
    LL ans = 1LL*n*(n+1)/2-1LL*(k+1)*k/2*(m+1)-(k+1)*((n-m)%(m+1));
    cout << ans << "\n";
}
 
int main() {
    ios::sync_with_stdio(false), cin.tie(0);
    //cout.setf(ios_base::showpoint);cout.precision(10);
    int t; cin >> t;
    while(t--)
    run_case();
    cout.flush();
    return 0;
}
View Code

猜你喜欢

转载自www.cnblogs.com/GRedComeT/p/12306592.html
今日推荐