10.11T3 曼哈顿距离->切比雪夫距离+离散化+树状数组+扫描线

世界第一的猛汉王

(mhw.cpp)

【问题描述】

卡普地公司举办了「世界第一的猛汉王」全球大会,来自世界各地的猛汉为了争夺「猛汉王」的名号前来一决高下。现在举行的是弓箭组选拔赛。卡普地公司为比赛新建了一张PVP地图——「猛汉竞技场」。有许多使用弓的猛汉在这里互相较量。他们中的一些装填了「接击瓶」,这使得他们在接近战中会占有一定优势,但是在远程战中会相当劣势。具体来说如下:

假设q装填了「接击瓶」而p没有,则当他们的曼哈顿距离大于D时,p压制q,反之q压制p。如果pq都装填了「接击瓶」或者都没有,则他们之间仍然会存在一个客观上的单向压制关系,但是在比赛刚开始时无法得知。

竞技场上一共有n+m个猛汉,其中n个装填了「接击瓶」,另外m个没有。每个猛汉降临到竞技场时有一个坐标(x, y)。Mark Douglas作为上一届的猛汉王正在观看这场比赛,他希望得知场上有多少个「猛汉三角」。「猛汉三角」是指三个人uvw满足u压制vv压制ww压制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

posted @ 2018-10-11 20:26  saionjisekai  阅读(87)  评论(0编辑  收藏  举报