http://acm.hdu.edu.cn/showproblem.php?pid=4417
这题刚开始的时候没想到,xianbin5说是先标记,再是离线查询。
因为他的查询操作和对改动数据的操作是分开的,也就是说可以把查询操作重新排序,按照自己的顺序来查询。
那么就可以想按照数据从大到小的顺序查询,当然事先是先把原来的数组存起来进行比较。。。就这样。。。(*´∀`*)
View Code
1 #include <iostream> 2 #include <algorithm> 3 #include <string.h> 4 #include <stdio.h> 5 using namespace std; 6 const int maxn = 100005; 7 long ans[maxn],n; 8 9 struct node 10 { 11 long num,order; 12 }temp[maxn]; 13 14 struct line 15 { 16 long s,r,h,order,ans; 17 }has[maxn]; 18 19 int lowbit(int x) 20 { 21 return x & (-x); 22 } 23 24 void mod(int x,int c) 25 { 26 while(x<maxn) 27 { 28 ans[x]+=c; 29 x+=lowbit(x); 30 } 31 } 32 33 long getSum(int x) 34 { 35 long sum=0; 36 while(x) 37 { 38 sum+=ans[x]; 39 x-=lowbit(x); 40 } 41 return sum; 42 } 43 44 bool cmp_temp(node a, node b) 45 { 46 return a.num < b.num; 47 } 48 49 bool cmp_has(line a, line b) 50 { 51 return a.h<b.h; 52 } 53 54 bool cmp_num(line a,line b) 55 { 56 return a.order < b.order; 57 } 58 59 int main() 60 { 61 long i,j,t,m,l; 62 scanf("%ld",&t); 63 for(l=1;l<=t;l++) 64 { 65 memset(ans,0,sizeof(ans)); 66 scanf("%ld%ld",&n,&m); 67 for(i=0;i<n;i++) 68 { 69 scanf("%ld",&temp[i].num); 70 temp[i].order=i+1; 71 } 72 sort(temp,temp+n,cmp_temp); 73 for(i=0;i<m;i++) 74 { 75 scanf("%ld%ld%ld",&has[i].s,&has[i].r,&has[i].h); 76 has[i].order=i; 77 } 78 sort(has,has+m,cmp_has); 79 j=0; 80 for(i=0;i<m;i++) 81 { 82 for(;j<n;j++) 83 { 84 if(temp[j].num<=has[i].h) 85 mod(temp[j].order,1); 86 else 87 break; 88 } 89 has[i].ans=getSum(has[i].r+1)-getSum(has[i].s); 90 } 91 sort(has,has+m,cmp_num); 92 printf("Case %d:\n",l); 93 for(i=0;i<m;i++) 94 printf("%ld\n",has[i].ans); 95 } 96 return 0; 97 }