hdu 3333 Turing Tree

题意:

  求某段区间内不同元素之和。

解法: 

  离线处理,将待询问区间按照右端点排序,然后依次将元素插入到线段树中,为了保证求得的结果都是不同元素之和,我们需要保证同一时刻某个元素在线段树中只能出现一次,如果之前插入了,那就先删除再在新位置插入。

  p.s.这题函数式线段树应该可以在线做,但是暂时没想到>_<

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cstring>
 4 #include<algorithm>
 5 using namespace std;
 6 typedef long long ll;
 7 const int N = (int)1e5+10;
 8 int num[N],X[N];
 9 ll sum[N<<2];
10 #define lson l,m,n<<1
11 #define rson m+1,r,n<<1|1
12 void pushup(int n){
13     sum[n] = sum[n<<1] + sum[n<<1|1];
14 }
15 void build(int l,int r,int n){
16     sum[n] = 0;
17     if(l==r)return;
18     int m=(l+r)>>1;
19     build(lson);
20     build(rson);
21     pushup(n);
22 }
23 void update(int pos,int flag,int l,int r,int n){
24     if(l==r){
25         if(flag)sum[n]+=num[l];
26         else sum[n]-=num[l];
27         return;
28     }
29     int m = (l+r)>>1;
30     if(pos<=m)update(pos,flag,lson);
31     else update(pos,flag,rson);
32     pushup(n);
33 }
34 ll query(int L,int R,int l,int r,int n){
35     if(L==l&&R==r)return sum[n];
36     int m=(l+r)>>1;
37     if(R<=m)return query(L,R,lson);
38     else if(L>m)return query(L,R,rson);
39     else return query(L,m,lson)+query(m+1,R,rson);
40 }
41 struct Query{
42     int L,R,id;
43     ll ans;
44 }Q[N];
45 bool cmp1(Query a,Query b){
46     return a.R<b.R||a.R==b.R&&a.L<b.L;
47 }
48 bool cmp2(Query a,Query b){
49     return a.id<b.id;
50 }
51 int pre[N];
52 int main(){
53     int T,n,m;scanf("%d",&T);
54     while(T--){
55         scanf("%d",&n);
56         for(int i=1;i<=n;i++){
57             scanf("%d",&num[i]);
58             X[i] = num[i];
59         }
60         sort(X+1,X+1+n);
61         int all = 1;
62         for(int i=2;i<=n;i++)
63             if(num[i]!=num[i-1])X[++all] = X[i];
64         fill(pre+1,pre+1+all,-1);
65         build(1,n,1);
66         scanf("%d",&m);
67         for(int i=0;i<m;i++){
68             scanf("%d%d",&Q[i].L,&Q[i].R);
69             Q[i].id = i;
70         }
71         sort(Q,Q+m,cmp1);
72         int now = 1;
73         for(int i=0;i<m;i++){
74             int right = Q[i].R;
75             while(now <= right){
76                 int hash = lower_bound(X+1,X+1+all,num[now])-X;
77                 if(pre[hash]==-1){
78                     update(now,1,1,n,1);
79                     pre[hash] = now;
80                 }else{
81                     update(pre[hash],0,1,n,1);
82                     update(now,1,1,n,1);
83                     pre[hash] = now;
84                 }
85                 now++;
86             }
87             Q[i].ans = query(Q[i].L,Q[i].R,1,n,1);
88         }
89         sort(Q,Q+m,cmp2);
90         for(int i=0;i<m;i++)
91             cout<<Q[i].ans<<endl;
92     }
93     return 0;
94 }

 

posted @ 2013-06-03 21:44  silver__bullet  阅读(160)  评论(0编辑  收藏  举报