jzoj6297-世界第一的猛汉王【切比雪夫距离,扫描线】
正題
題目大意
有若干個(gè)紅點(diǎn)和藍(lán)點(diǎn),對(duì)于每一對(duì)紅點(diǎn)和藍(lán)點(diǎn),若距離大于DDD則藍(lán)點(diǎn)壓制紅點(diǎn),否則紅點(diǎn)壓制藍(lán)點(diǎn)。然后紅點(diǎn)和藍(lán)點(diǎn)之間也有不定的壓制關(guān)系。
求有多少個(gè)三角要求AAA壓制BBB,BBB壓制CCC,CCC壓制AAA且至少包含一個(gè)紅點(diǎn)和藍(lán)點(diǎn)。求三角數(shù)量的最小值和最大值。
解題思路
我們考慮最暴力的做法先,我們可以枚舉兩個(gè)相同顏色的點(diǎn),枚舉他們之間的關(guān)系,然后找三角。
我們定義covxcov_xcovx?表示在xxx的DDD范圍以內(nèi)與他異色的點(diǎn)的數(shù)量,covx,ycov_{x,y}covx,y?表示同時(shí)在x,yx,yx,y兩個(gè)點(diǎn)的DDD范圍內(nèi)的異色點(diǎn)的數(shù)量,對(duì)于包含兩個(gè)紅色點(diǎn)的方案數(shù)為
∑x,y∈redmax{covx?covx,y,covy?covx,y}\sum_{x,y\in red}max\{cov_x-cov_{x,y},cov_{y}-cov_{x,y}\}x,y∈red∑?max{covx??covx,y?,covy??covx,y?}
∑x,y∈redmax{covx,covy}?covx,y\sum_{x,y\in red}max\{cov_x,cov_y\}-cov_{x,y}x,y∈red∑?max{covx?,covy?}?covx,y?
∑x,y∈redmax{covx,covy}?∑z∈bluecovx,y\sum_{x,y\in red}max\{cov_x,cov_y\}-\sum_{z\in blue} cov_{x,y}x,y∈red∑?max{covx?,covy?}?z∈blue∑?covx,y?
那我們發(fā)現(xiàn)對(duì)于每個(gè)藍(lán)點(diǎn)zzz被統(tǒng)計(jì)的次數(shù)就是Ccovz2C_{cov_z}^{2}Ccovz?2?
?∑x,y∈redmax{covx,covy}?∑z∈blueCcovz2\Rightarrow \sum_{x,y\in red}max\{cov_x,cov_y\}-\sum_{z\in blue} C_{cov_z}^{2}?x,y∈red∑?max{covx?,covy?}?z∈blue∑?Ccovz?2?
然后我們發(fā)現(xiàn)如果計(jì)算出covcovcov數(shù)組即可在O(nlog?n)O(n\log n)O(nlogn)的時(shí)間內(nèi)統(tǒng)計(jì)答案(排個(gè)序瞎搞搞就好)
那如何統(tǒng)計(jì)covcovcov數(shù)組,我們可以將每個(gè)點(diǎn)(x,y)(x,y)(x,y)轉(zhuǎn)換為(x?y,x+y)(x-y,x+y)(x?y,x+y)然后將曼哈頓距離轉(zhuǎn)換為切比雪夫距離。這樣我們發(fā)現(xiàn)covcovcov就是在(x,y)(x,y)(x,y)這個(gè)點(diǎn)為中心的2D?2D2D*2D2D?2D的矩陣包含的點(diǎn)的個(gè)數(shù),用掃描線統(tǒng)計(jì)即可。
codecodecode
#include<cstdio> #include<cstring> #include<algorithm> #define ll long long using namespace std; const ll N=200100; struct node{ll x,y; }a[N],b[N]; ll n,m,D,y[N*3],mov,maxs,mins,covn[N],covm[N],cnt; struct Seq_node{struct Tree_node{ll l,r,w;}t[N*16];void Build(ll x,ll l,ll r){t[x].l=l;t[x].r=r;if(l==r) return;ll mid=(l+r)/2;Build(x*2,l,mid);Build(x*2+1,mid+1,r);}ll Ask(ll x,ll l,ll r){if(t[x].l==l&&t[x].r==r)return t[x].w;ll mid=(t[x].l+t[x].r)/2;if(r<=mid) return Ask(x*2,l,r);else if(l>mid) return Ask(x*2+1,l,r);else return Ask(x*2,l,mid)+Ask(x*2+1,mid+1,r);}void Change(ll x,ll pos,ll val){if(t[x].l==t[x].r){t[x].w+=val;return;}ll mid=(t[x].l+t[x].r)/2;if(pos<=mid) Change(x*2,pos,val);else Change(x*2+1,pos,val);t[x].w=t[x*2].w+t[x*2+1].w;} }T; bool cMp(node x,node y) {return x.x<y.x;} int main() {freopen("mhw.in","r",stdin);freopen("mhw.out","w",stdout);scanf("%lld%lld%lld",&n,&m,&D);for(ll i=1;i<=n;i++){ll X,Y;scanf("%lld%lld",&X,&Y);a[i].x=X+Y;a[i].y=X-Y;y[++cnt]=a[i].y;y[++cnt]=a[i].y+D;y[++cnt]=a[i].y-D;}for(ll i=1;i<=m;i++){ll X,Y;scanf("%lld%lld",&X,&Y);b[i].x=X+Y;b[i].y=X-Y;y[++cnt]=b[i].y;y[++cnt]=b[i].y+D;y[++cnt]=b[i].y-D;} sort(b+1,b+1+m,cMp);sort(a+1,a+1+n,cMp);sort(y+1,y+1+cnt);cnt=unique(y+1,y+1+cnt)-(y+1);T.Build(1,1,cnt);ll l=0,r=0;for(ll i=1;i<=n;i++){while(l<m&&b[l+1].x<a[i].x-D){ll Y=lower_bound(y+1,y+1+cnt,b[++l].y)-y;T.Change(1,Y,-1);}while(r<m&&b[r+1].x<=a[i].x+D){ll Y=lower_bound(y+1,y+1+cnt,b[++r].y)-y;T.Change(1,Y,1);}ll L=lower_bound(y+1,y+1+cnt,a[i].y-D)-y,R=lower_bound(y+1,y+1+cnt,a[i].y+D)-y;covn[i]=T.Ask(1,L,R);}while(l<m){ll Y=lower_bound(y+1,y+1+cnt,b[++l].y)-y;T.Change(1,Y,-1);}while(r<m){ll Y=lower_bound(y+1,y+1+cnt,b[++r].y)-y;T.Change(1,Y,1);}l=0,r=0;for(ll i=1;i<=m;i++){while(l<n&&a[l+1].x<b[i].x-D){ll Y=lower_bound(y+1,y+1+cnt,a[++l].y)-y;T.Change(1,Y,-1);}while(r<n&&a[r+1].x<=b[i].x+D){ll Y=lower_bound(y+1,y+1+cnt,a[++r].y)-y;T.Change(1,Y,1);}ll L=lower_bound(y+1,y+1+cnt,b[i].y-D)-y,R=lower_bound(y+1,y+1+cnt,b[i].y+D)-y;covm[i]=T.Ask(1,L,R);}sort(covn+1,covn+1+n);sort(covm+1,covm+1+m);for(ll i=1;i<=n;i++)maxs+=covn[i]*(i-1),mins+=covn[i]*(n-i),mov+=covn[i]*(covn[i]-1)/2;for(ll i=1;i<=m;i++)maxs+=covm[i]*(i-1),mins+=covm[i]*(m-i),mov+=covm[i]*(covm[i]-1)/2;printf("%lld %lld",mins-mov,maxs-mov); }總結(jié)
以上是生活随笔為你收集整理的jzoj6297-世界第一的猛汉王【切比雪夫距离,扫描线】的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: jzoj6293-迷宫【ddp,线段树,
- 下一篇: 王水是什么 王水的简单介绍