bzoj[SCOI2007]降雨量

来源:互联网 发布:js函数数组参数传递 编辑:程序博客网 时间:2024/06/11 13:44

做了一个多星期的降雨量终于AC了!!!!(又一个星期后yzh又优化了代码——在之前的下面~)

(此处应有掌声~~)
这一道题是线段树+离散化,难点在于有的年份没有数据怎么办。数据给出的年份就枚举各种情况,一种一种完成。其他的在线段树中多定义一个bk,true代表这个节点管辖的所有点都有人(即这个范围的年份都有数据),false反之。bo是代表这个范围内最大的数有没有重复,因为题目是要求第二个给出的年份要比第一个给出的年份以后的所有年份大。

#include<cstdio>#include<iostream>#include<cstring>#include<algorithm>#include<cmath>#include<map>using namespace std;map<int,int>mp;struct node{    int x,k,q;}a[51000];int n,m,p,d[51000];struct trnode{    int l,r,lc,rc,c;    bool bk,bo;}tr[210000];int trlen;void bt(int l,int r){    trlen++;int now=trlen;    tr[now].l=l;tr[now].r=r;tr[now].c=0;    tr[now].lc=tr[now].rc=-1;tr[now].bk=false;tr[now].bo=true;    if(l<r)    {        int mid=(l+r)/2;        tr[now].lc=trlen+1;bt(l,mid);        tr[now].rc=trlen+1;bt(mid+1,r);    }}void change(int now,int p,int c){    if(tr[now].l==tr[now].r){tr[now].c=c;tr[now].bk=true;return ;}    int lc=tr[now].lc,rc=tr[now].rc;    int mid=(tr[now].l+tr[now].r)/2;    if(p<=mid)change(lc,p,c);    else      change(rc,p,c);    tr[now].c=max(tr[lc].c,tr[rc].c);    if(tr[lc].c==tr[rc].c)tr[now].bo=false;    else tr[now].bo=tr[lc].c>tr[rc].c?tr[lc].bo:tr[rc].bo;    if(tr[lc].bk==true&&tr[rc].bk==true)tr[now].bk=true;}int findmax(int now,int l,int r,bool &bb){    if(tr[now].l==l&&tr[now].r==r)    {        if(tr[now].bo==false)bb=false;        return tr[now].c;    }    int lc=tr[now].lc,rc=tr[now].rc;    int mid=(tr[now].l+tr[now].r)/2;    if(r<=mid)    {        bool bl=true;        int llc=findmax(lc,l,r,bl);        bb=bl;return llc;    }    else if(mid+1<=l)    {        bool br=true;        int rrc=findmax(rc,l,r,br);        bb=br;return rrc;    }    else     {        bool bl=true,br=true;        int llc=findmax(lc,l,mid,bl);        int rrc=findmax(rc,mid+1,r,br);        if(llc>rrc){bb=bl;return llc;}        if(llc<rrc){bb=br;return rrc;}        if(llc==rrc){bb=false;return llc;}    }}bool wen(int now,int l,int r){    if(tr[now].l==l&&tr[now].r==r){return tr[now].bk;}    if(tr[now].l<=l&&r<=tr[now].r&&tr[now].bk==true)return true;    int lc=tr[now].lc,rc=tr[now].rc;    int mid=(tr[now].l+tr[now].r)/2;    if(r<=mid)       return wen(lc,l,r);    else if(mid+1<=l)return wen(rc,l,r);    else return wen(lc,l,mid)&wen(rc,mid+1,r);}int cmp(const void *xx,const void *yy){    node n1=*(node *)xx;    node n2=*(node *)yy;    return n1.x-n2.x;}void lisan(){    p=1;    int fr=a[1].x;a[1].x=p;d[1]=a[1].k;    mp.insert(pair<int,int>(fr,a[1].x));    for(int i=2;i<=n;i++)    {        p++;        if(a[i].x-1!=fr){d[p]=-1;p++;}        fr=a[i].x;a[i].x=p;d[p]=a[i].k;        mp.insert(pair<int,int>(fr,a[i].x));    }}int erfen(int x){    int l=1,r=n,ab=99999999,ans;    while(l<=r)    {        int mid=(l+r)/2;        if(x>a[mid].q)l=mid+1;        else        {            if(ab>a[mid].q-x)            {                ab=a[mid].q-x;                ans=a[mid].q;            }            r=mid-1;        }    }    return mp[ans];}int erfen2(int x){    int l=1,r=n,ab=99999999,ans;    while(l<=r)    {        int mid=(l+r)/2;        if(x>a[mid].q)        {            if(ab>x-a[mid].q)            {                ab=x-a[mid].q;                ans=a[mid].q;            }            l=mid+1;        }        else r=mid-1;    }    return mp[ans];}int main(){    freopen("rain.in","r",stdin);    freopen("rain.out","w",stdout);    scanf("%d",&n);    for(int i=1;i<=n;i++){scanf("%d%d",&a[i].x,&a[i].k);a[i].q=a[i].x;}    qsort(a+1,n,sizeof(node),cmp);lisan();    trlen=0;bt(1,p);    for(int i=1;i<=n;i++)        change(1,a[i].x,a[i].k);    scanf("%d",&m);    for(int i=1;i<=m;i++)    {        int x,y;scanf("%d%d",&x,&y);bool bb=true;        if(mp[x]!=0&&mp[x+1]!=0&&mp[y]!=0)        {            if(d[mp[x]]<d[mp[y]]){printf("false\n");continue;}            x=mp[x+1];y=mp[y];            int k=findmax(1,x,y,bb);            if(k==d[y]&&bb==true)            {                if(wen(1,x,y)==true)printf("true\n");                else printf("maybe\n");                continue;            }            else printf("false\n");            continue;        }        if(mp[y]==0)        {            y=erfen2(y);int u;            if(mp[x]==0){printf("maybe\n");continue;}            else u=d[mp[x]];            if(mp[x+1]==0)x=erfen(x+1);            else x=mp[x+1];            if(x>y){printf("maybe\n");continue;}            int k=findmax(1,x,y,bb);            if(k>=u)printf("false\n");            else printf("maybe\n");            continue;        }        else        {            y=mp[y];            if(mp[x]==0)            {                if(mp[x+1]!=0)x=mp[x+1];                else x=erfen(x+1);                int k=findmax(1,x,y,bb);                if(k==d[y]&&bb==true)printf("maybe\n");                else printf("false\n");                continue;            }            else            {                if(d[mp[x]]<d[y]){printf("false\n");continue;}                x=erfen(x+1);                int k=findmax(1,x,y,bb);                if(k==d[y]&&bb==true)printf("maybe\n");                else printf("false\n");                continue;            }        }    }    return 0;}

好了现在是降雨量2.0

将bo简化掉了,因为只要问x+1~y-1就OK了~

#include<cstdio>#include<iostream>#include<cstring>#include<algorithm>#include<cmath>#include<map>using namespace std;map<int,int>mp;struct node{    int x,k,q;}a[51000];int n,m,p,d[51000];struct trnode{    int l,r,lc,rc,c;    bool bk;}tr[210000];int trlen;void bt(int l,int r){    trlen++;int now=trlen;    tr[now].l=l;tr[now].r=r;tr[now].c=0;    tr[now].lc=tr[now].rc=-1;tr[now].bk=false;    if(l<r)    {        int mid=(l+r)/2;        tr[now].lc=trlen+1;bt(l,mid);        tr[now].rc=trlen+1;bt(mid+1,r);    }}void change(int now,int p,int c){    if(tr[now].l==tr[now].r){tr[now].c=c;tr[now].bk=true;return ;}    int lc=tr[now].lc,rc=tr[now].rc;    int mid=(tr[now].l+tr[now].r)/2;    if(p<=mid)change(lc,p,c);    else      change(rc,p,c);    tr[now].c=max(tr[lc].c,tr[rc].c);    if(tr[lc].bk==true&&tr[rc].bk==true)tr[now].bk=true;}int findmax(int now,int l,int r){    if(tr[now].l==l&&tr[now].r==r)return tr[now].c;    int lc=tr[now].lc,rc=tr[now].rc;    int mid=(tr[now].l+tr[now].r)/2;    if(r<=mid)return findmax(lc,l,r);    else if(mid+1<=l)return findmax(rc,l,r);    else return max(findmax(lc,l,mid),findmax(rc,mid+1,r));}bool wen(int now,int l,int r){    if(tr[now].l==l&&tr[now].r==r){return tr[now].bk;}    if(tr[now].l<=l&&r<=tr[now].r&&tr[now].bk==true)return true;    int lc=tr[now].lc,rc=tr[now].rc;    int mid=(tr[now].l+tr[now].r)/2;    if(r<=mid)       return wen(lc,l,r);    else if(mid+1<=l)return wen(rc,l,r);    else return wen(lc,l,mid)&wen(rc,mid+1,r);}int cmp(const void *xx,const void *yy){    node n1=*(node *)xx;    node n2=*(node *)yy;    return n1.x-n2.x;}void lisan(){    p=1;    int fr=a[p].x;a[p].x=p;d[p]=a[p].k;    mp.insert(pair<int,int>(fr,a[p].x));    for(int i=2;i<=n;i++)    {        p++;        if(a[i].x-1!=fr){d[p]=-1;p++;}        fr=a[i].x;a[i].x=p;d[p]=a[i].k;        mp.insert(pair<int,int>(fr,a[i].x));    }}int erfenx(int x){    int l=1,r=n,ab=99999999,ans;    while(l<=r)    {        int mid=(l+r)/2;        if(x>a[mid].q)l=mid+1;        else        {            if(ab>a[mid].q-x)            {                ab=a[mid].q-x;                ans=a[mid].q;            }            r=mid-1;        }    }    return mp[ans];}int erfeny(int y){    int l=1,r=n,ab=99999999,ans;    while(l<=r)    {        int mid=(l+r)/2;        if(y>=a[mid].q)        {            if(ab>y-a[mid].q)            {                ab=y-a[mid].q;                ans=a[mid].q;            }            l=mid+1;        }        else r=mid-1;    }    return mp[ans];}int main(){    freopen("rain.in","r",stdin);    freopen("rain.out","w",stdout);    scanf("%d",&n);int mmin,mmax;    for(int i=1;i<=n;i++){scanf("%d%d",&a[i].x,&a[i].k);a[i].q=a[i].x;}    qsort(a+1,n,sizeof(node),cmp);lisan();    mmin=a[1].q;mmax=a[n].q;    trlen=0;bt(1,p);    for(int i=1;i<=n;i++)change(1,a[i].x,a[i].k);    scanf("%d",&m);    for(int i=1;i<=m;i++)    {        int x,y;scanf("%d%d",&x,&y);        if(y<=mmin){printf("maybe\n");continue;}        if(x>=mmax){printf("maybe\n");continue;}        if(x+1==y)        {            if(mp[x]!=0&&mp[y]!=0)            {                    if(d[mp[x]]<d[mp[y]]){printf("false\n");continue;}                    else {printf("true\n");continue;}            }            else printf("maybe\n");            continue;        }        if(mp[x]!=0&&mp[y]!=0)        {            if(d[mp[x]]<d[mp[y]]){printf("false\n");continue;}            int xx=erfenx(x+1);            int yy=erfeny(y-1);            if(xx>yy){printf("maybe\n");continue;}            int k=findmax(1,xx,yy);            if(k<d[mp[y]])            {                    if(wen(1,mp[x],mp[y])==true)printf("true\n");                    else printf("maybe\n");            }            else printf("false\n");            continue;        }        if(mp[x]==0&&mp[y]==0){printf("maybe\n");continue;}        if(mp[x]==0)        {            int xx=erfenx(x+1),yy=erfeny(y-1);            if(xx>yy){printf("maybe\n");continue;}            int k=findmax(1,xx,yy);            if(k<d[mp[y]])printf("maybe\n");            else printf("false\n");            continue;        }        if(mp[y]==0)        {            int xx=erfenx(x+1),yy=erfeny(y-1);            if(xx>yy){printf("maybe\n");continue;}            int k=findmax(1,xx,yy);            if(k>=d[mp[x]])printf("false\n");            else printf("maybe\n");            continue;        }    }    return 0;}

By_yzh

2 1
原创粉丝点击