[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 }