模考T2题解

这道题目暴力的话是会超时的,所以我们想到数学优化:正难则反。

我们先求出所有方案数再减去不合法的就是合法的方案数。

首先总方案数比较好求用隔板法,就是我们将 L 分给不同的三个数,可以不分给一个数,那么为了解决可以不分给一个数的情况,我们可以将 L3 加上的这三个可以理解为“假的”也就是你分到了这“假的”数,你的数值是不会增加了,然后我们要分给 3 个数,方案数就是: C^3_{L+3}

那么,不合法的数呢?大家都知道三角形两边之和大于第三边,于是我们可以得出三种不合法情况 (a+x)≥(b+y)+(c+z)(b+y)≥(a+x)+(c+z)(c+z)≥(a+x)+(b+y) 这里的 x,y,z 分别表示给 a,b,c 加上的数。

接下来我们以 (a+x)≥(b+y)+(c+z) 为例:我们可以变换一下不等式也就变成了 x ≥ y+z + (b+c-a) 这个时候会分成两种情况:

  1. k = b+c-a ≥ 0 这个时候 k 为非负数直接枚举 y+z 的值。
  2. k<0 这个时候条件变成 x ≥ y+z - |k| 这个时候我们需要分块处理。

好了,现在就可以写出大体代码框架了:

#include<bits/stdc++.h>
#define I using
#define AK namespace
#define IOI std
#define i_ak return
#define ioi  0
#define int long long
I AK IOI;
int a,b,c,l,sum,ans;
int check1(int L,int k){
   /*当k为非负数的时候*/
}
int check2(int L,int k){
    /*当k为负数的时候*/
}
int f(int k,int L){
    if(k>=0){
        if(L<k)return 0;//如果L小于K直接返回 0
        else return check1(L,k);当k为为负数时枚举k+z
    }
	else return check2(L,-k);//当k为负数的时候分成2快理
}
signed main(){
    /*输入*/
    sum=(l+3)*(l+2)*(l+1)/6;//总方案数 C^{3}_{L+3}
    int k1=b+c-a,k2=a+c-b,k3=a+b-c;
    int sum1=f(k1,l),sum2=f(k2,l),sum3=f(k3,l);//三种不合法的情况的数目
	ans=sum-(sum1+sum2+sum3);//容斥原理这就是最后的答案
    /*输出*/
    i_ak ioi;
}

分析一下复杂度:

  • 时间复杂度: O(L) 不会超市!放心提交!
  • 空间复杂度: O(1) 没有额外空间。
2 个赞

不会超市!放心提交!

@zhangyizhen ?怎么了

“超市”

@叶润天 @zhangyizhen 玩个谐音不行吗?

666

1 个赞

捉,叶润天

@2345安全卫士 为什么要捉,又不是失踪人口

????!!!!!

他昨天才回归 \texttt{QaQ}

@2345安全卫士 没有!

真的吗 \texttt{QaQ}

@2345安全卫士 假的/dx,嘟嘟嘟,我要做题了T3不会呀,T4错了一个点不知道为什么。

tql