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
- [bzoj][SCOI2007]降雨量
- 【BZOJ 1067】 [SCOI2007]降雨量
- bzoj 1067: [SCOI2007]降雨量
- bzoj 1067 [SCOI2007]降雨量
- bzoj[SCOI2007]降雨量
- bzoj 1067: [SCOI2007]降雨量
- [bzoj] 1067: [SCOI2007]降雨量
- BZOJ 1067: [SCOI2007]降雨量
- BZOJ 1067 [SCOI2007]降雨量 RMQ
- bzoj 1067: [SCOI2007]降雨量 RMQ+讨论
- BZOJ 1067 [SCOI2007]降雨量 线段树
- 【BZOJ 1067】[SCOI2007]降雨量 线段树
- scoi2007降雨量
- 【SCOI2007】降雨量
- [SCOI2007]降雨量
- BZOJ 1067: [SCOI2007]降雨量 二分,RM0Q预处理,分类讨论
- bzoj1067: [SCOI2007]降雨量
- 【SCOI2007】【BZOJ1067】降雨量
- JAVA-根据给定日期获得获得一周(中国周)的日期
- ARM指令集详解
- 关于LeetCode中Linked List Cycle一题的理解
- 阿里开源技术一览
- LSHForest进行文本相似性计算
- bzoj[SCOI2007]降雨量
- 2016年值得学习的五大开源项目
- nodejs express项目使用log4js
- 黑马程序员:那些年永远忘记不了的老师的话
- ZigBee按键允许入网
- Java设计模式——代理模式实现及原理
- web.xml 中的过滤器(拦截器)Filter与监听器Listener的作用和区别?
- 还是主席树
- html 入门笔记