[Hackerrank題目選做] Jim And Challenges
阿新 • • 發佈:2018-12-24
題目大意: 給定d維空間的n個點,每個點有權值h[i],求sigma(i=1...n,j=i+1...n,h[i]*h[j]*dis(i,j))的值,其中dis(i,j)是兩點的曼哈頓距離,d<=4,n<=100000.
題解: 根據曼哈頓距離的性質,每一維之間兩兩獨立,所以可以分開來計算,
對於每一維,所要計算的值為sigma(i=1...n,j=i+1...n,(x[j]-x[i])*h[i]*h[j]),
先通過排序去絕對值,再考慮每一項對於答案的貢獻,
通過拆項,可以發現該貢獻即為x[i]*h[i]*sigma(j=1...i-1,h[j])-h[j]*sigma(j=1...i-1,x[j]*h[j]).
然後預處理一下字首和就行了---------時間複雜度O(dnlogn).
其實我不是很懂為什麼hr說這題是計算幾何啊? Interesting....
Code:
#include <bits/stdc++.h> #define ll long long #define mod 1000000009ll using namespace std; struct node {ll h,p[5]; }t[300005]; ll p1[300005],p2[300005]; int n,d; inline bool cmp(node a,node b) {return a.p[0]<b.p[0];} int main (){ int i,j; scanf ("%d%d",&n,&d); for (i=1;i<=n;i++) {scanf ("%lld",&t[i].h); for (j=1;j<=d;j++) {scanf ("%lld",&t[i].p[j]);} } ll ans=0; for (j=1;j<=d;j++) {for (i=1;i<=n;i++) {t[i].p[0]=t[i].p[j];} sort(t+1,t+n+1,cmp); for (i=1;i<=n;i++) {ans+=(((t[i].p[0]*t[i].h)%mod)*p1[i-1])%mod;ans%=mod; ans-=((t[i].h*p2[i-1])%mod);ans%=mod; if (ans<0) {ans+=mod;} p1[i]=p1[i-1]+t[i].h;p1[i]%=mod; p2[i]=p2[i-1]+t[i].p[0]*t[i].h;p2[i]%=mod; } } printf ("%lld",ans); return 0; }