SEERC2018 Broken Clock

SEERC2018 Broken Clock

Problem Statement

时针, 分针, 秒针的程度分别为 A , B , C A,B,C A,B,C, 并且假设时钟共有 N N N个时刻. 并且由于时钟被破坏时针, 分针和秒针可以指向任意一时刻, 问时针, 分针和秒针能够形成多少个包含时针中心的三角形.

Solution

我们考虑三角形的生成函数. 假设时针分针和秒针组成三角形的三条边分别为 a , b , c a,b,c a,b,c, 那么他们所对应的圆心角应该有 θ 1 + θ 2 + θ 3 = 2 π \theta_1+\theta_2+\theta_3=2\pi θ1+θ2+θ3=2π. 由于 N N N个时刻, 每个时刻所对应圆心角相等, 所以角度有 N N N等分. 当然由于包含时针中心且能组成三角形那么 2 π N ≤ θ 1 , θ 2 , θ 3 ≤ π \frac{2\pi}{N}\leq\theta_1,\theta_2,\theta_3\leq\pi N2πθ1,θ2,θ3π.

则对于一个圆心角的生成函数为 F ( x ) = ( ∑ i = 1 ⌊ N 2 ⌋ x i ) = x 1 − x ⌊ N 2 ⌋ 1 − x F(x)=(\sum_{i=1}^{\lfloor\frac{N}{2}\rfloor}x^i)=x\frac{1-x^{\lfloor\frac{N}{2}\rfloor}}{1-x} F(x)=(i=12Nxi)=x1x1x2N.

则三角形的生成函数为 G ( x ) = F ( x ) 3 = x 3 ( 1 − x ⌊ N 2 ⌋ 1 − x ) 3 = x 3 ( 1 − x ⌊ N 2 ⌋ ) 3 ∑ i ≥ 0 C n + 2 2 G(x)=F(x)^3=x^3(\frac{1-x^{\lfloor\frac{N}{2}\rfloor}}{1-x})^3=x^3(1-x^{\lfloor\frac{N}{2}\rfloor})^3\sum_{i\geq0}C_{n+2}^2 G(x)=F(x)3=x3(1x1x2N)3=x3(1x2N)3i0Cn+22.

则三角形个数应当为 C n t = [ x n ] G ( x ) = C N + 2 − 3 2 − C 3 1 × C N − ⌊ N 2 ⌋ − 3 + 2 2 Cnt=[x^n]G(x)=C_{N+2-3}^2-C_{3}^1\times C_{N-\lfloor\frac{N}{2}\rfloor-3+2}^2 Cnt=[xn]G(x)=CN+232C31×CN2N3+22.

那么若默认三条边不等的情况下答案应当为 A n s = C n t × 2 N Ans=Cnt\times2N Ans=Cnt×2N.

若其中两条边相等则 A n s = C n t × 2 N × 1 2 ! Ans=Cnt\times 2N\times\frac{1}{2!} Ans=Cnt×2N×2!1.

若其中三条边相等则 A n s = C n t × 2 N × 1 3 ! Ans=Cnt\times 2N\times\frac{1}{3!} Ans=Cnt×2N×3!1.

Code

# define Fast_IO std::ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
# include "unordered_map"
# include "algorithm"
# include "iostream"
# include "cstdlib"
# include "cstring"
# include "cstdio"
# include "vector"
# include "bitset"
# include "queue"
# include "cmath"
# include "ctime"
# include "map"
# include "set"
# define ll long long
# define ld long double
# define rep1(i,a,b) for(ll i=(a);i<=(b);i++)
# define rep2(i,a,b) for(ll i=(b);i>=(a);i--)
# define pii pair<int,int>
# define pll pair<ll,ll>
# define ph push_back
# define pb pop_back
# define eb emplace_back
# define vi vector<int>
# define vll vector<ll>
# define vpi vector<pii >
# define vpll vector<pll >
# define ri(x) scanf("%d",&x)
# define rf(x) scanf("%f",&x)
# define rl(x) scanf("%lld",&x)
# define rd(x) scanf("%lf",&x)
# define rs(s) scanf("%s",s+1)
# define wi(x) printf("%d",x)
# define wl(x) printf("%lld",x)
# define ws(s) printf("%s",s+1)
# define all(v) v.begin(),v.end()
# define fi first
# define se second
# define lowbit(x) ((x)&(-(x)))
# define repauto(Name,v) for(auto Name:v)
# define Endl "\n"
# define ENDL putchar('\n')
using namespace std;
template<class I> inline I GCD(I A,I B){return B?GCD(B,A%B):A;}
template<class I> inline I LCM(I A,I B){return A/GCD(A,B)*B;}
template<class I> I Sqrt(I N){
	I sqrtN=sqrt(N)-1;
	while(sqrtN+1<=N/(sqrtN+1))sqrtN++;
	return sqrtN;
}
template<class I> I Pow(I X,I Y,__int128 Mod1=998244353){
	static __int128 Ans; Ans=1;
	for(;Y;Y>>=1,X=(__int128)X*X%Mod1) if(Y&1) Ans=Ans*X%Mod1;
	return Ans;
}

__int128 Get(__int128 A,__int128 B){
	return A*(A-1)/2;
}
unsigned long long A,B,C,N;
int main(){
# ifdef LH_Frank
    freopen("1.in","r",stdin);
	freopen("1.out","w",stdout);
# endif
	cin>>A>>B>>C>>N;
	__int128 Ans=Get(N+2-3,2)-3*Get(N-N/2-3+2,2);
	if(A==B && B==C){
		Ans=Ans*N/3;
	}else if(A==B || A==C || B==C){
		Ans=Ans*N;
	}else Ans=Ans*N*2;
	cout<<(unsigned long long)(Ans);
	return 0;
}
/*
15000 15000 15000 2 0
5000 10000 15000 3 6
15000 15000 15000 3 1
15000 15000 15000 4 4
15000 15000 15000 5 5
15000 15000 15000 6 14

*/
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值