球员

来源:互联网 发布:台式win10网络显示红叉 编辑:程序博客网 时间:2024/04/29 20:32

给出很多球员的能力值、年份、名字,有很多个查询,给出某一个年份范围,求出范围内能力值从高到低排列的11个球员,如果能力值相同则按年份从低到高排,如果年份仍相同,则按名字的字典序排。

先sort年份,名字;再转化为求区间最大值。

#include<cstdio>#include<cstring>#include<string.h>#include<algorithm>#include<iostream>#include<math.h>#include<vector>using namespace std;const int maxn=50001;struct treenode{int a,b;int mm[11],len;}tree[maxn*4];struct heronode{int year;char name[16];int power;}hero[maxn];int id[maxn],n,request;int min(int x,int y){return x<y?x:y;}bool cmp(int x,int y){if(hero[x].year!=hero[y].year)return hero[x].year<hero[y].year;return strcmp(hero[x].name,hero[y].name)<0;}int bsearchl(int low,int high,int x){int ret=-1,mid;while(low<=high){mid=(low+high)/2;if(x<=hero[id[mid]].year){high=mid-1;ret=mid;}else{low=mid+1;}}return ret;}int bsearchr(int low,int high,int x){int ret=-1,mid;while(low<=high){mid=(low+high)/2;if(x>=hero[id[mid]].year){ret=mid;low=mid+1;}else{high=mid-1;}}return ret;}bool read(){int i;int ret=scanf("%d",&n);if(ret!=1)return false;for(int i=0;i<n;i++)scanf("%d%s%d",&hero[i].year,&hero[i].name,&hero[i].power);for(i=0;i<n;i++)id[i]=i;sort(id,id+n,cmp);return true;}void build(int x,int y,int k){tree[k].a=x;tree[k].b=y;tree[k].len=min(11,y-x+1);int mid=(x+y)/2;if(y-x>=1){build(x,mid,2*k+1);build(mid+1,y,2*k+2);}else{tree[k].mm[0]=id[x];return;}int i,p,q,nn,mm;nn=tree[2*k+1].len;mm=tree[2*k+2].len;i=0;p=0;q=0;while(i<tree[k].len){if(q>=mm||(p<nn&&hero[tree[k*2+1].mm[p]].power>=hero[tree[2*k+2].mm[q]].power))tree[k].mm[i++]=tree[k*2+1].mm[p++];elsetree[k].mm[i++]=tree[k*2+2].mm[q++];}}void getans(int x,int y,int k,int ans[]){int ans1[11],ans2[11];if(y>=tree[k].b&&x<=tree[k].a){for(int i=0;i<tree[k].len;i++)ans[i]=tree[k].mm[i];return;}int mid=(tree[k].a+tree[k].b)/2,nn=0,mm=0;if(x<=mid){getans(x,y,k*2+1,ans1);nn=min(11,min(mid-x+1,mid-tree[k].a+1));}if(y>=mid+1){getans(x,y,k*2+2,ans2);mm=min(11,min(y-mid,tree[k].b-mid));}int len=min(11,nn+mm);int i=0,p=0,q=0;while(i<len){if(q>=mm||(p<nn&&hero[ans1[p]].power>=hero[ans2[q]].power))ans[i++]=ans1[p++];elseans[i++]=ans2[q++];}}int main(){int x,y,ans[11],i;while(read()){build(0,n-1,0);scanf("%d",&request);while(request--){scanf("%d%d",&x,&y);x=bsearchl(0,n-1,x);y=bsearchr(0,n-1,y);if(y>=x)getans(x,y,0,ans);int len=min(11,y-x+1);for(i=0;i<len;i++){printf("%s\n",hero[ans[i]].name);}for(;i<11;i++){printf("XXX\n");}printf("\n");}}return 0;}

from sysuoj.


原创粉丝点击