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 }