[线段树][扫描线][计数] Jzoj P6297 世界第一的猛汉王

Description

 

题解

  •  

代码

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <iostream>
 4 #include <algorithm> 
 5 #define ll long long
 6 #define N 100010 
 7 using namespace std;
 8 ll n,m,lim,mn,mx,tot,cnt,d[N*6],c[2][N];
 9 struct tree { ll l,r,sum[2]; }t[N*25];
10 struct line 
11 {
12     ll x,op,col,id,l,r;
13     bool operator <(const line &a)const { return x!=a.x?x<a.x:op<a.op; }
14 }p[N*6];
15 void build(ll d,ll l,ll r) 
16 {
17     t[d].l=l,t[d].r=r;
18     if (l==r) return;
19     ll mid=l+r>>1;
20     build(d*2,l,mid),build(d*2+1,mid+1,r);
21 }
22 void modify(ll d,ll l,ll r,ll tag,ll f) 
23 {
24     if (t[d].l>r||t[d].r<l) return ;
25     if (l<=t[d].l&&t[d].r<=r) { t[d].sum[tag]+=f; return; }
26     modify(d*2,l,r,tag,f),modify(d*2+1,l,r,tag,f);
27 }
28 ll query(ll d,ll pos,ll tag) 
29 {
30     if (t[d].l>pos||t[d].r<pos) return 0;
31     if (t[d].l==t[d].r) return t[d].sum[tag];
32     return query(d*2,pos,tag)+query(d*2+1,pos,tag)+t[d].sum[tag];
33 }
34 void work() { for (ll i=1;i<=cnt;i++) if (p[i].op==-1) modify(1,p[i].l,p[i].r,p[i].col,1); else if(p[i].op==0)  c[p[i].col][p[i].id]=query(1,p[i].l,p[i].col^1); else modify(1,p[i].l,p[i].r,p[i].col,-1); }
35 int main() 
36 {
37     freopen("mhw.in","r",stdin),freopen("mhw.out","w",stdout),scanf("%lld%lld%lld",&n,&m,&lim);
38     for (ll i=1,a,b,x,y;i<=n;i++) scanf("%lld%lld",&a,&b),x=a+b,y=a-b,p[++cnt]=(line){x-lim,-1,0,i,y-lim,y+lim},p[++cnt]=(line){x,0,0,i,y},p[++cnt]=(line){x+lim,1,0,i,y-lim,y+lim},d[++d[0]]=y,d[++d[0]]=y+lim,d[++d[0]]=y-lim;
39     for (ll i=1,a,b,x,y;i<=m;i++) scanf("%lld%lld",&a,&b),x=a+b,y=a-b,p[++cnt]=(line){x-lim,-1,1,i,y-lim,y+lim},p[++cnt]=(line){x,0,1,i,y},p[++cnt]=(line){x+lim,1,1,i,y-lim,y+lim},d[++d[0]]=y,d[++d[0]]=y+lim,d[++d[0]]=y-lim;
40     sort(p+1,p+1+cnt),sort(d+1,d+1+d[0]),tot=unique(d+1,d+1+d[0])-d;
41     for (ll i=1;i<=cnt;i++) p[i].l=lower_bound(d+1,d+tot,p[i].l)-d,p[i].r=lower_bound(d+1,d+tot,p[i].r)-d;
42     build(1,1,tot),work();
43     for (ll i=1;i<=m;i++) c[1][i]=n-c[1][i];
44     sort(c[0]+1,c[0]+1+n),sort(c[1]+1,c[1]+1+m);
45     for (ll i=1,x;i<=n;i++) mn+=(n-i)*c[0][i],mx+=(i-1)*c[0][i],x=1ll*(m-c[0][i])*(m-c[0][i]-1)/2,mn-=x,mx-=x;
46     for (ll i=1,x;i<=m;i++) mn+=1ll*(m-i)*c[1][i],mx+=1ll*(i-1)*c[1][i],x=1ll*(n-c[1][i])*(n-c[1][i]-1)/2,mn-=x,mx-=x;
47     printf("%lld %lld",mn,mx);
48 }

 

posted @ 2019-08-12 21:22  BEYang_Z  阅读(275)  评论(0编辑  收藏  举报