HDU 5233 Gunner II 离散化
题目链接:
hdu:http://acm.hdu.edu.cn/showproblem.php?pid=5233
bc(中文):http://bestcoder.hdu.edu.cn/contests/contest_chineseproblem.php?cid=585&pid=1002
题解:
离散化之后,存在一张表里面(相同的值的id号用链表串起来,倒着存),每次查询完就把表首的删了,继续查。
之前离散的时候没有把查询的一起加进去,就一直t,估计是查询的时候很多是没有结果的,就会比较耗时间。改成一起哈希之后就过了。也没有做读写优化。
代码:
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<map> 5 #include<algorithm> 6 using namespace std; 7 typedef long long LL; 8 9 const int maxn=2e5+10; 10 11 struct Edge{ 12 int v,ne; 13 Edge(int v,int ne):v(v),ne(ne){}; 14 Edge(){}; 15 }egs[maxn]; 16 17 int n,m; 18 19 int head[maxn],tot; 20 int ha[maxn]; 21 int arr[maxn],q[maxn]; 22 //将元素加入邻接表 23 void addEdge(int x,int id){ 24 egs[tot]=Edge(id,head[x]); 25 head[x]=tot++; 26 } 27 //查询并删除 28 int queEdge(int x){ 29 int p=head[x]; 30 if(p==-1) return -2; 31 int ret=egs[p].v; 32 head[x]=egs[p].ne; 33 return ret; 34 } 35 /* 36 離散化去重 37 void get_ID(){ 38 sort(ha,ha+n+m); ha[n+m]=ha[n+m-1]-1; 39 int cur=0; 40 for(int i=0;i<n+m;i++){ 41 if(ha[i]!=ha[i+1]){ 42 ha[cur++]=ha[i]; 43 } 44 } 45 ha[n+m]=cur; 46 */ 47 48 //二分 49 int find(int x){ 50 int lef=0,rig=ha[n+m]; 51 int ret=-1; 52 while(lef<rig){ 53 int mid=lef+(rig-lef)/2; 54 if(ha[mid]<x){ 55 lef=mid+1; 56 }else if(ha[mid]>x){ 57 rig=mid; 58 }else{ 59 ret=mid; 60 break; 61 } 62 } 63 return ret; 64 } 65 66 void init(){ 67 memset(head,-1,sizeof(head)); 68 tot=0; 69 } 70 71 int main(){ 72 while(scanf("%d%d",&n,&m)==2&&n){ 73 init(); 74 //将输入的数和查询的数一起做离散化 75 for(int i=0;i<n;i++){ 76 scanf("%d",arr+i); 77 ha[i]=arr[i]; 78 } 79 for(int i=0;i<m;i++){ 80 scanf("%d",q+i); 81 ha[n+i]=q[i]; 82 } 83 //离散化 84 sort(ha,ha+n+m); 85 ha[n+m]=unique(ha,ha+n+m)-ha; 86 87 //倒着插入,这样只要每次删除表首的数就可以了 88 for(int i=n-1;i>=0;i--){ 89 int x=find(arr[i]); 90 addEdge(x,i); 91 } 92 for(int i=0;i<m;i++){ 93 int x=find(q[i]); 94 printf("%d\n",queEdge(x)+1); 95 } 96 } 97 return 0; 98 } 99 100 /* 101 5 5 102 1 2 3 4 1 103 1 3 1 4 9 104 */