hdu5820 询问简单路径 主席树

来源:互联网 发布:软件产品设计流程 编辑:程序博客网 时间:2024/06/06 02:18

题意:在一个大小为50000*50000的矩形中,有n个路灯。(n<=500000)

询问是否每一对路灯之间存在一条道路,使得长度为|x1 – x2| + |y1 – y2|且每个拐弯点都是路灯。


ps注意 实现的时候下方y要+1(边界问题) 主席树root维是记录的x棵树的前缀的树根,每棵树记录的是y的分布情况

#include <bits/stdc++.h>using namespace std;#define maxn 9000000#define lson l,mid,rt<<1#define rson mid,r+1,rt<<1|1#define getmid int mid=(l+r)>>1;#define mem(x,v) memset(x,v,sizeof(x));#define ft first#define sd second#define mp make_pair#define pii pair<int,int>int n,flag;map<pii,int>myp;int siz;int sum[maxn],ls[maxn],rs[maxn];int root[51000];void build(int &rt,int l,int r){    siz++;rt=siz;    sum[rt]=0;    if (l==r) return;    getmid    build(ls[rt],l,mid);    build(rs[rt],mid+1,r);    sum[rt]=sum[ls[rt]]+sum[rs[rt]];}void update(int l,int r,int x,int &y,int pos,int val){    siz++;y=siz;    if (l==r)    {        sum[y]=sum[x]+val;        return;    }    ls[y]=ls[x]; rs[y]=rs[x];    getmid    if (pos <= mid) update(l,mid,ls[x],ls[y],pos,val);    else update(mid+1,r,rs[x],rs[y],pos,val);    sum[y]=sum[ls[y]]+sum[rs[y]];}int query(int l,int r,int rt,int x,int y){    if (x<=l && r<=y)    {        return sum[rt];    }    getmid    int res=0;    if (x <= mid) res+=query(l,mid,ls[rt],x,y);    if (mid <  y) res+=query(mid+1,r,rs[rt],x,y);    return res;}int mx[51000],my[51000];pii po[501000];void solve(){    mem(mx,0);mem(my,0);    siz=0;    build(root[0],1,50000);    int last=root[0],x1,x2,y1,y2,sum1=0,sum2=0;    for (int i=1;i<=n;i++)    {        x1=po[i].ft; y1=po[i].sd;        x2=po[my[y1]].ft; y2=po[mx[x1]].sd;        update(1,50000,last,root[x1],y1,1);        sum1=query(1,50000,root[x1],y2+1,y1);        sum2=query(1,50000,root[x2],y2+1,y1);        if(sum1-sum2!=1)        {            flag=0;            return;        }        mx[x1]=i; my[y1]=i; last=root[x1];    }}int main(){    int T;    while (~scanf("%d",&n))    {        if (n==0) break;        myp.clear();        int num=0;        for (int i=1;i<=n;i++)        {            int x,y;            scanf("%d%d",&x,&y);            if(!myp[mp(x,y)])            {                myp[mp(x,y)]=1;                num++;                po[num]=mp(x,y);            }        }        n=num;flag=1;        sort(po+1,po+n+1);        solve();        for (int i=1;i<=n;i++) po[i].ft=50001-po[i].ft;        sort(po+1,po+n+1);        solve();        printf("%s\n",flag ? "YES" : "NO" );    }}/*51 11 21 32 13 3*/


原创粉丝点击