世界第一的猛汉王
(mhw.cpp)
【问题描述】
卡普地公司举办了「世界第一的猛汉王」全球大会,来自世界各地的猛汉为了争夺「猛汉王」的名号前来一决高下。现在举行的是弓箭组选拔赛。卡普地公司为比赛新建了一张PVP地图——「猛汉竞技场」。有许多使用弓的猛汉在这里互相较量。他们中的一些装填了「接击瓶」,这使得他们在接近战中会占有一定优势,但是在远程战中会相当劣势。具体来说如下:
假设q装填了「接击瓶」而p没有,则当他们的曼哈顿距离大于D时,p压制q,反之q压制p。如果p和q都装填了「接击瓶」或者都没有,则他们之间仍然会存在一个客观上的单向压制关系,但是在比赛刚开始时无法得知。
竞技场上一共有n+m个猛汉,其中n个装填了「接击瓶」,另外m个没有。每个猛汉降临到竞技场时有一个坐标(x, y)。Mark Douglas作为上一届的猛汉王正在观看这场比赛,他希望得知场上有多少个「猛汉三角」。「猛汉三角」是指三个人u、v、w满足u压制v,v压制w,w压制u,且三人中至少有一人装填了「接击瓶」且至少有一人没有。由于场上尚存在一些不明了的压制关系,所以Mark希望知道可能的「猛汉三角」数量的最小值和最大值。
【输入格式】
输入文件名为mhw.in。
输入第一行为三个正整数nmD。
接下来n行每行两个正整数x y,表示装填了「接击瓶」的猛汉的坐标。
接下来m行每行两个正整数x y,表示没有装填「接击瓶」的猛汉的坐标。
可能有多个猛汉站在同一个位置。
【输出格式】
输出文件名为mhw.out。
输出两个数minmax,表示答案的最小值和最大值。
【样例输入与输出】
example_mhw1.in |
example_mhw1.out |
2 2 1 1 2 1 1 3 1 2 2 |
0 2 |
更多样例请见example/mhw/目录。
【数据范围】
对于1~2号测试点(20%):。
对于1~5号测试点(50%):。
对于6~7号测试点(20%):。
对于所有测试点(100%):。
code(DLZ的):
1 #include<algorithm> 2 #include<iostream> 3 #include<cstring> 4 #include<cstdio> 5 using namespace std; 6 #define int long long 7 typedef long long LL; 8 const int N=100005; 9 int n,m,D,X[N<<3],Y[N<<3],cx,cy,f[N*6],s1[N],s2[N]; 10 struct Node{int x,y;}a[N],b[N]; 11 struct Query{int x,y,tmp,id;}qa[N<<2],qb[N<<2]; 12 inline int Lowbit(int i){return i&-i;} 13 inline void Add(int x){ 14 for(int i=x;i<600000;i+=Lowbit(i))++f[i]; 15 } 16 inline int Ask(int x){ 17 int ans=0; 18 for(int i=x;i;i-=Lowbit(i))ans+=f[i]; 19 return ans; 20 } 21 bool cmp(Node A,Node B){return A.x<B.x;} 22 bool cmp2(Query A,Query B){return A.x<B.x;} 23 inline LL Cal(int a,int bb){ 24 if(a<bb)return 0; 25 return 1LL*a*(a-1)/2; 26 } 27 signed main(){ 28 int x,y,cnt1=0,cnt2=0; 29 scanf("%lld%lld%lld",&n,&m,&D); 30 for(int i=1;i<=n;++i){ 31 scanf("%lld%lld",&x,&y); 32 a[i].x=x-y;a[i].y=x+y; 33 Y[++cy]=a[i].y;//对y离散化 34 Y[++cy]=a[i].y+D; 35 Y[++cy]=a[i].y-D-1; 36 qa[++cnt1]=(Query){a[i].x+D,a[i].y+D,1,i}; 37 qa[++cnt1]=(Query){a[i].x+D,a[i].y-D-1,-1,i}; 38 qa[++cnt1]=(Query){a[i].x-D-1,a[i].y+D,-1,i}; 39 qa[++cnt1]=(Query){a[i].x-D-1,a[i].y-D-1,1,i}; 40 } 41 for(int i=1;i<=m;++i){ 42 scanf("%lld%lld",&x,&y); 43 b[i].x=x-y;b[i].y=x+y; 44 Y[++cy]=b[i].y; 45 Y[++cy]=b[i].y+D; 46 Y[++cy]=b[i].y-D-1; 47 qb[++cnt2]=(Query){b[i].x+D,b[i].y+D,1,i}; 48 qb[++cnt2]=(Query){b[i].x+D,b[i].y-D-1,-1,i}; 49 qb[++cnt2]=(Query){b[i].x-D-1,b[i].y+D,-1,i}; 50 qb[++cnt2]=(Query){b[i].x-D-1,b[i].y-D-1,1,i}; 51 } 52 sort(Y+1,Y+cy+1); 53 sort(a+1,a+n+1,cmp); 54 sort(b+1,b+m+1,cmp); 55 sort(qa+1,qa+cnt1+1,cmp2); 56 sort(qb+1,qb+cnt2+1,cmp2); 57 int py=unique(Y+1,Y+cy+1)-Y; 58 for(int i=1;i<=n;++i)a[i].y=lower_bound(Y+1,Y+py,a[i].y)-Y; 59 for(int i=1;i<=m;++i)b[i].y=lower_bound(Y+1,Y+py,b[i].y)-Y; 60 int pos=1; 61 for(int i=1;i<=cnt1;++i){ 62 while(pos<=m&&b[pos].x<=qa[i].x)Add(b[pos].y),++pos; 63 qa[i].y=lower_bound(Y+1,Y+py,qa[i].y)-Y; 64 s1[qa[i].id]+=qa[i].tmp*Ask(qa[i].y); 65 } 66 memset(f,0,sizeof(f));pos=1; 67 for(int i=1;i<=cnt2;++i){ 68 while(pos<=n&&a[pos].x<=qb[i].x)Add(a[pos].y),++pos; 69 qb[i].y=lower_bound(Y+1,Y+py,qb[i].y)-Y; 70 s2[qb[i].id]+=qb[i].tmp*Ask(qb[i].y); 71 } 72 sort(s1+1,s1+n+1);sort(s2+1,s2+m+1); 73 long long ans=0,ans2=0; 74 for(int i=1;i<=n;++i){ 75 ans+=1LL*s1[i]*(i-1); 76 ans2+=1LL*s1[n-i+1]*(i-1); 77 ans-=Cal(s1[i],2); 78 ans2-=Cal(s1[i],2); 79 } 80 for(int i=1;i<=m;++i){ 81 ans+=1LL*s2[i]*(i-1); 82 ans2+=1LL*s2[m-i+1]*(i-1); 83 ans-=Cal(s2[i],2); 84 ans2-=Cal(s2[i],2); 85 } 86 cout<<ans2<<' '<<ans; 87 return 0; 88 }
over