A.Numbers
B.Broken Watch
先考虑最简单的情况,就是a,b,c都相等的情况,这个时候答案显然只会跟n有关系,在n个线段里面选3个的情况就是C(n,3),其中有一部分不合法,这个时候考虑怎样是不合法的,现在设取三条边分别是x,y,z;当x经过y到达z的这个角的角度小于180度的时候,那么这个方案必然是不合法的,这样的话只需要确定x和z就可以确定一族不可行的方案,x和z可以夹1....[n/2](上取整)条边,也就是形成了[n/2](上取整)族答案,每一族的方案数分别是1...[n/2]。于是用总的方案数减去(1+2+3+...+[n/2](上取整))即可。这里的答案是对2^64取模,因此统计答案时要处理一下除法。
对于a,b,c不相等的情况直接乘上A(3,1)或A(3,3)即可
#include<bits/stdc++.h> using namespace std; typedef unsigned long long ll; int main(){ int a,b,c; ll n; scanf("%d%d%d%llu",&a,&b,&c,&n); ll tmp=(n+1)/2; tmp-=2; ll ans=0; //特判除以6的情况 ll tmp1=n,tmp2=n-1,tmp3=n-2; if(tmp1%2==0) tmp1/=2; else if((tmp2)%2==0) tmp2/=2; if(tmp1%3==0) tmp1/=3; else if(tmp2%3==0) tmp2/=3; else if(tmp3%3==0) tmp3/=3; ans=tmp1*tmp2*tmp3; ans-=n*(tmp*(tmp+1)/2); if(a!=b&&b!=c&&c!=a){//全都不相同 ans*=6; } else if(a!=b||a!=c||b!=c){//有一个不同 ans*=3; } printf("%llu\n",ans); return 0; }