zoukankan      html  css  js  c++  java
  • 「CF1301C Ayoub's function」

    本题结论题,所以就不放前置芝士了.

    具体做法

    先将最终的答案分为两部分,区间(开始于结束为止不同)和点,点的个数非常显然就是M,于是要计算区间的个数,可以发现如果直接计算有多少合法区间很麻烦,所以用总共的区间数(frac{N*(N-1)}{2}),减去没有的部分,可以发现这M个1可以将这个区间分成M+1段0(长度可以为0),两段之间有1的0之间不会相互影响,所以没有的部分就是每一段0中的区间个数之和,对于每一段0中的区间个数,设一个函数(f(x)=frac{x*(x-1)}{2}),可以发现这是一个二次函数,然后经过感谢理解,当每一段长度尽可能相等时最终的没有0的区间个数才是最少,所以可以计算出两个数(num1)(num2),(num1)为长度为(lfloor frac{N-M}{M+1} floor+1)的连续0的段数,(num2)为长度为(lfloor frac{N-M}{M+1} floor)的连续0的段数,然后将长度带入函数,再乘上相应的区间数,在总区间数中减去,就可以知道至少含有一个1的区间个数了,最终答案只要再加上一个M就好了.

    代码

    #include<bits/stdc++.h>
    #define REP(i,first,last) for(int i=first;i<=last;++i)
    #define DOW(i,first,last) for(int i=first;i>=last;--i)
    using namespace std;
    long long N,M;
    int T;
    void work()
    {
    	scanf("%lld%lld",&N,&M);
    	long long len=(N-M)/(M+1);//计算出长度
    	long long num1=(N-M-len*(M+1));//因为这个长度是向下取整的随意可能有剩余,而长度为len+1的个数自然就是剩余的0的个数了
    	long long num2=M+1-num1;//因为总共有M+1段
    	long long answer=N*(N-1)-len*(len+1)*num1-len*(len-1)*num2;//计算
    	answer/=2;//前面没有除二
    	printf("%lld
    ",answer+M);//最后答案加上M之后输出
    }
    int main()
    {
    	scanf("%d",&T);
    	REP(i,1,T)
    	work();
    	return 0;
    }
    
  • 相关阅读:
    Leetcode Reverse Words in a String
    topcoder SRM 619 DIV2 GoodCompanyDivTwo
    topcoder SRM 618 DIV2 MovingRooksDiv2
    topcoder SRM 618 DIV2 WritingWords
    topcoder SRM 618 DIV2 LongWordsDiv2
    Zepto Code Rush 2014 A. Feed with Candy
    Zepto Code Rush 2014 B
    Codeforces Round #245 (Div. 2) B
    Codeforces Round #245 (Div. 2) A
    Codeforces Round #247 (Div. 2) B
  • 原文地址:https://www.cnblogs.com/Sxy_Limit/p/12307505.html
Copyright © 2011-2022 走看看