牛客的Latex问题好多,完全没法用。由于你逆天牛反复屏蔽我剪贴板链接,我只能放个图片了。**************。
以下是文本.
题解 | #木棍#
逆天,怎么这题都是神仙做法?又是矩阵又是拉格朗日插值的。
实际上很简单就可以 。
由于我个人习惯,以下OI中更常用的记号 表示
。注意上下是相反的。
不妨设原木棍长为 ,变出来的木棍为 p,q,r ,不妨设 s<p<q<r <= 4s。
不难注意到,合法的情况远远多于不合法的情况。所以我们考虑正难则反,由于我们已经认定了 s<p<q<r <= 4s,首先总方案数是在[s+1,4s] 选三个不同数,排序得到的方案数,所以是 。现在我们只要找出在同样的限制下,不合法的方案数。
容易发现,在我们的限制条件下,一个方案是不合法的,那么必须有:
s+p<= q
p+q<= r
r<= 4s
否则大的就可以和小的两个构成三角形。
那么我们可以枚举 ,然后每次可以
求出
都确定时,不合法的
的总数(也就是 4s-p-q+1),从而求出所有不合法的方案数,复杂度
。
考虑卡常,我们优化上下界,不枚举不符合限制的情况。
为什么要不枚举超出限制的情况呢?因为只有这样,我们这个式子里每一个才都会对不合法情况有贡献。
具体地,首先我们枚举 。那就先找
的范围。
由于 s+p <= q ,s<p ,可以得到:
4s>= r>= p+q >= s+2p
所以有
s+2p<= 4s
p<= 3s/2
(逆天,你牛Latex打不出加号!以下用--表示+)
由于都是整数,有
确定
的范围后,我们枚举
,所以我们现在要在已知
的情况下求出
的范围。
因为 ,所以
已知 时,符合限制的不合法
满足
,所以不合法的
有
个。
现在我们有了一个小常数 算法,写成式子就是:
我当时在场上把这暴力一打完,我大呼这题不就做完了??
如果你还没看出来,我们首先把后面那里【与 有关的项】与【与
无关的项】分离。
所以 对于每个 ,枚举
时
都会被算
次。所以原式等于
后面用等差数列求和:
这样我们就有了 做法。但这还不够。
大力展开:
还是一样的技巧,把与 无关的扔到外面去。
后面利用 和等差数列求和 :
这是不合法情况.所以合法方案数是:
手残可能打错公式,如公式与代码不一致请以代码为准.
#include<bits/stdc++.h>
#define int __int128//毒瘤操作
using namespace std;
const int mod = 1e9 + 7;
int n;
int tot;
int inva;//不合法情况
int qpow(int b, int e)
{
int res = 1;
while(e)
{
// printf("%lld\n", e);
if(e & 1) (res *= b) %= mod;
(b *= b) %= mod; e >>= 1;
}
return res;
}//快速幂其实可以不要,因为inv2和inv6都是常数.懒得改了.
int inv2, inv6;
template<class io>
inline void re(io &x)
{
char c=getchar();x=0;
while(c<48 || c>57)c=getchar();
while(c>47 && c<58)x=(x<<3)+(x<<1)+(c&15),c=getchar();
return;
}//快读
template<class io>
void wr(io x)
{
io d=x/10;if(d)wr(d);
putchar(x-(d<<3)-(d<<1)|48);return;
}//快写
signed main()
{
// freopen("c.in", "r", stdin);
re(n); inv2 = qpow(2, mod - 2); inv6 = qpow(6, mod - 2);
tot = (3 * n) % mod * (3 * n - 1) % mod * (3 * n - 2) % mod * inv6 % mod;
inva = (3*n/2 - n)*((n*n%mod + n)%mod * 9 * inv2 % mod + 1) % mod;
int lim = 3*n/2;
(inva += 2*lim*(lim + 1)%mod*(2*lim + 1)%mod*inv6%mod) %= mod;
((inva -= 2*n*(n + 1)%mod*(2*n + 1)%mod*inv6%mod) += mod) %= mod;
(inva -= (3 + 6*n)*(n + 1 + lim)%mod*(lim - n)%mod*inv2%mod + mod) %= mod;
(inva += mod) %= mod;
wr((tot - inva + mod) % mod);
return 0;
}