[线段树][扫描线][计数] Jzoj P6297 世界第一的猛汉王
题解
代码
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 }