2018.12.08【NOIP提高組】模擬B組
阿新 • • 發佈:2018-12-16
遲到的解題報告
JZOJ 5123 diyiti
分析
6根木棍,只能是3+1+1+1或者是2+2+1+1,所以分類討論。(以下其它情況都排除了之前的情況,也就是容斥
設邊長為 ( 代表 )
2+2+1+1的組合方式 |
---|
以下保證 |
3+1+1+1的組合方式 |
---|
這樣講好像很簡單,實際上實踐會比較容易在細節上出問題,我的細節出錯點詳見程式碼
程式碼
#include <cstdio>
#include <cctype>
#include <algorithm>
#include <vector>
#define rr register
using namespace std;
const int N=10000001;
typedef long long ll; ll ans;
vector<int>t; int cnt[N+10],dcnt[N+10];
inline signed iut(){
rr int ans=0; rr char c=getchar();
while (!isdigit(c)) c=getchar();
while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
return ans;
}
signed main(){
freopen("yist.in","r",stdin);
freopen("yist.out","w",stdout);
for (rr int n=iut(),x;n;--n)
if (++cnt[x=iut()]==1) t.push_back(x);
sort(t.begin(),t.end());
for (rr int i=0;i<t.size()-1;++i)
for (rr int j=i+1;j<t.size();++j)
if (t[i]+t[j]<N)
dcnt[t[i]+t[j]]+=cnt[t[i]]*cnt[t[j]];//原始碼只是=
else break;
for (rr int i=1;i<t.size();++i){
if (cnt[t[i]]==1) continue;
if (cnt[t[i]]>1){
rr ll x=1ll*cnt[t[i]]*(cnt[t[i]]-1)>>1,sum=0;
if (!(t[i]&1)&&cnt[t[i]>>1]>3)
ans+=x*cnt[t[i]>>1]*(cnt[t[i]>>1]-1)*(cnt[t[i]>>1]-2)*(cnt[t[i]>>1]-3)/3>>3;//原始碼判成奇數
for (rr int j=0;j<i;++j)
if ((t[j]<<1)<t[i]){
if (cnt[t[j]]>1&&cnt[t[i]-t[j]]>1)
sum+=1ll*cnt[t[j]]*(cnt[t[j]]-1)*cnt[t[i]-t[j]]*(cnt[t[i]-t[j]]-1)>>2;
}else break;
ans+=x*sum; sum=0;
for (rr int j=0;j<i;++j)
if ((t[j]<<1)<t[i]){
if (cnt[t[i]-t[j]])
ans+=x*sum*cnt[t[j]]*cnt[t[i]-t[j]],sum+=cnt[t[j]]*cnt[t[i]-t[j]];
}else break;
if (!(t[i]&1)) ans+=x*sum*cnt[t[i]>>1]*(cnt[t[i]>>1]-1)>>1;//原始碼未判斷
}
if (cnt[t[i]]==2