标签:des style blog http io ar color os sp
题目链接:
题意:就是给出狠点建筑的坐标和高度,然后给出很多询问,求在这个坐标右下角的第k矮的建筑。。
思路:太弱了我,这个题目从上个星期天就开始看,但是一直不会,所以只能看别人思路,因为那个k小于10,所以左右节点只取前十就可以了,但是我觉得万一不记录完全万一发生丢失怎么办,后来一想sb了,如果左右节点都取前10的话,那么根节点得到的20个值,在排序必定取到了前10啊。。。言归正传,这道题因为数据范围太大了,前对建筑和询问一起排序,按x从小到大,再按y从小到大,在按建筑优先的原则排序。所以先对坐标y进行离散化,然后建树,然后开始插入,然后对节点进行维护(只需要维护前10个值就可以了),然后这个问题就解决了。。。我觉得和cf的一个题很像。。。
ps:我这个题敲了几遍,觉得收货很大。。还有就是这题数据太弱了,直接暴力也可以过,并且跑的比线段树的快多了。。。
题目:
5 2 1 1 1 2 2 2 3 3 3 4 4 4 5 5 5 0 0 1 6 3 2
-1 2
代码:
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; const int maxn=60000+10; struct Node { int x,y,id,flag,h; void init() { scanf("%d%d%d",&x,&y,&h); } }node[maxn]; struct Tree { int sum,xx[25]; }tree[maxn<<2]; int n,m,cnt,top[maxn],ans[maxn],x,cc,FB[maxn]; bool cmp(Node a,Node b) { if(a.x!=b.x) return a.x<b.x; if(a.y!=b.y) return a.y<b.y; return a.flag<b.flag; } void push_up(int dex) { int k=0; for(int i=1;i<=tree[dex<<1].sum;i++) tree[dex].xx[++k]=tree[dex<<1].xx[i]; for(int i=1;i<=tree[dex<<1|1].sum;i++) tree[dex].xx[++k]=tree[dex<<1|1].xx[i]; tree[dex].sum=k; sort(tree[dex].xx+1,tree[dex].xx+1+tree[dex].sum); if(k>10) tree[dex].sum=10; } void buildtree(int dex,int l,int r) { tree[dex].sum=0; memset(tree[dex].xx,0,sizeof(tree[dex].xx)); if(l==r) return; int mid=(l+r)>>1; buildtree(dex<<1,l,mid); buildtree(dex<<1|1,mid+1,r); } void Update(int dex,int l,int r,int pos,int val) { if(l==r) { tree[dex].xx[++tree[dex].sum]=val; sort(tree[dex].xx+1,tree[dex].xx+1+tree[dex].sum); if(tree[dex].sum>10) tree[dex].sum=10; return; } int mid=(l+r)>>1; if(pos<=mid) Update(dex<<1,l,mid,pos,val); else Update(dex<<1|1,mid+1,r,pos,val); push_up(dex); } void Query(int dex,int l,int r,int L,int R) { if(L<=l&&R>=r) { for(int i=1;i<=tree[dex].sum;i++) FB[++cc]=tree[dex].xx[i]; sort(FB+1,FB+1+cc); if(cc>10) cc=10; return; } int mid=(l+r)>>1; if(L<=mid) Query(dex<<1,l,mid,L,R); if(R>mid) Query(dex<<1|1,mid+1,r,L,R); } int main() { while(~scanf("%d%d",&n,&m)) { cnt=0; for(int i=1;i<=n+m;i++) { node[i].init(); node[i].id=i; top[++cnt]=node[i].y; if(i<=n) node[i].flag=0; else node[i].flag=1; } sort(node+1,node+1+n+m,cmp); sort(top+1,top+1+cnt); x=unique(top+1,top+1+cnt)-(top+1); buildtree(1,1,x); for(int i=1;i<=n+m;i++) { int pos=lower_bound(top+1,top+1+x,node[i].y)-top; if(!node[i].flag) Update(1,1,x,pos,node[i].h); else { cc=0; Query(1,1,x,1,pos); if(cc<node[i].h) ans[node[i].id]=-1; else ans[node[i].id]=FB[node[i].h]; } } for(int i=n+1;i<=n+m;i++) printf("%d\n",ans[i]); } return 0; }
hdu5107 K-short Problem(线段树+离散化+思维)
标签:des style blog http io ar color os sp
原文地址:http://blog.csdn.net/u014303647/article/details/41379839