2 1 1 5 10 4 2 3 1 4 4 8 1 4 6
0 1 2 1
1 //本题的关键是离散化,不然数组的空间不能开那么大,接下来运用树状数组来存储,查找,问题便可迎刃而解 2 3 #include <cstdio> 4 #include <cstring> 5 #include <algorithm> 6 using namespace std; 7 const int MAX = 300010; 8 //测试数据有点水,将 MAX 改为100010 也能过 9 typedef struct Node 10 { 11 int num; 12 int id; //id为记录输入的顺序,是建立一一映射的关键 13 }Node; 14 Node s[MAX]; 15 int a[MAX],c[MAX]; 16 17 int cmp(const void *a,const void *b) 18 { 19 return (*(Node *)a).num - (*(Node *)b).num; 20 } 21 22 int lowbit(int i) 23 { 24 return i&(-i); 25 } 26 27 void add(int i,int value) 28 { 29 while(i<MAX) 30 { 31 c[i]+=value; 32 i+=lowbit(i); 33 } 34 } 35 36 int sum(int i) 37 { 38 int t=0; 39 while(i>0) 40 { 41 t+=c[i]; 42 i-=lowbit(i); 43 } 44 return t; 45 } 46 47 int main() 48 { 49 int T; 50 scanf("%d",&T); 51 while(T--) 52 { 53 int i,j,n,m,total,count; 54 memset(c,0,sizeof(c)); 55 scanf("%d%d",&n,&m); 56 total=n*2+m;// 把所有要输入的数据综合到一块,然后建立一一映射的关系(把大数变成小数,以缩小存储空间) 57 for(i=0;i<total;i++) 58 { 59 scanf("%d",&s[i].num); 60 s[i].id=i; 61 } 62 qsort(s,total,sizeof(s[0]),cmp); 63 count = 1;a[s[0].id]=count; 64 for(i=1;i<total;i++)//大数变小,建立成映射关系 65 { 66 if(s[i].num!=s[i-1].num) 67 a[s[i].id]=++count; 68 else 69 a[s[i].id]=count; 70 } 71 for(i=0;i<n*2;i+=2)//更新树状数组结点信息(插线取点法) 72 { 73 add(a[i],1); 74 add(a[i+1]+1,-1); 75 } 76 for(i=n*2;i<total;i++) 77 printf("%d\n",sum(a[i])); 78 } 79 return 0; 80 } 81 //a树状数组 + 离散化
树状数组 + 离散化
nyoj_600_花儿朵朵_201404162000,布布扣,bubuko.com
原文:http://www.cnblogs.com/xl1027515989/p/3670316.html