[BZOJ 1878][SDOI2009]HH的项链 (离线,树状数组)

分析看这个大神的,我的还是参考他说的算法实现的:http://www.dxmtb.com/blog/diff/ 

 

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<algorithm>
 5 using namespace std;
 6 const int maxm = 1000005;
 7 const int maxn = 50005;
 8 
 9 
10 int C[maxn],next[maxn],B[maxn];
11 int flag[maxm];
12 struct query{
13     int l,r;
14     int qnum,ans;
15 }Q[200005]; 
16 int N,M;
17 int cmp1(query a,query b){
18     if(a.l == b.l) return a.r < b.r;
19     else           return a.l < b.l;
20 }
21 int cmp2(query a,query b){
22     return a.qnum < b.qnum;
23 }
24 int lowbit(int x){
25     return x&(-x);
26 }
27 int sum(int x){
28     int temp = 0;
29     while(x >= 1){
30         temp += C[x];
31         x -= lowbit(x);
32     }
33     return temp;
34 }
35 void update(int x,int num){
36     while(x <= N){
37         C[x] += num;
38         x += lowbit(x);
39     }
40     return;
41 }
42 int main()
43 {
44     //if(freopen("input.txt","r",stdin)== NULL)  {printf("Error\n"); exit(0);}
45     cin>>N;
46     memset(flag,-1,sizeof(flag));
47     memset(C,0,sizeof(C));
48     memset(B,0,sizeof(B));
49     memset(next,0,sizeof(next));
50        for(int i=1;i<=N;i++){
51            int a;
52            scanf("%d",&a);
53            if(flag[a]== -1){
54                flag[a] = i;  
55                B[i] = 1;
56            }
57            else{
58                next[flag[a]] = i;
59                flag[a] = i;
60            }
61     }
62     for(int i=1;i<=N;i++)
63       for(int j=i-lowbit(i)+1;j<=i;j++){
64            C[i] += B[j]; 
65       }
66     cin>>M;
67     for(int i=1;i<=M;i++){
68         scanf("%d%d",&Q[i].l,&Q[i].r);
69         Q[i].qnum = i;
70     }
71     sort(Q+1,Q+M+1,cmp1); 
72     int pv = 1;
73     for(int i=1;i<=N;i++){
74         while(Q[pv].l == i){
75             Q[pv].ans = sum(Q[pv].r) - sum(Q[pv].l -1);
76                        //printf("%d %d %d %d\n",Q[pv].r,sum(Q[pv].r) ,Q[pv].l -1,sum(Q[pv].l -1));
77             pv++;   //for(int i=1;i<=N;i++) printf("%d ",C[i]); printf("\n");
78         }
79         if(next[i]) {
80             update(next[i],1);
81             update(i,-1);
82         }
83         
84     }
85     sort(Q+1,Q+M+1,cmp2);
86     for(int i=1;i<=M;i++){
87         printf("%d\n",Q[i].ans);
88     }
89     return 0;
90 }
View Code

 

posted @ 2013-06-03 18:31  等待最好的两个人  阅读(415)  评论(0编辑  收藏  举报