您的位置:首页 > 其它

HDU3333 Turing Tree 离线树状数组

2016-08-05 16:07 274 查看
题意:统计一段区间内不同的数的和

分析:排序查询区间,离线树状数组

#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL;
const int N = 3e4+5;
const int mod = 1e9+7;
LL c
;
int n,q,x,y,T,pre
;
struct Node{
int v,id;
}a
;
bool cmpv(Node a,Node b){
if(a.v==b.v)return a.id<b.id;
return a.v<b.v;
}
bool cmpid(Node a,Node b){
return a.id<b.id;
}
void add(int x,LL t){
for(int i=x;i<=n;i+=i&(-i))c[i]+=t;
}
LL ask(int x){
LL ret=0;
for(int i=x;i;i-=i&(-i))ret+=c[i];
return ret;
}
struct Que{
int l,r,id;
bool operator<(const Que &rhs)const{
return r<rhs.r;
}
}p[100000];
LL ret[100000];
int main(){
scanf("%d",&T);
while(T--){
scanf("%d",&n);
for(int i=1;i<=n;++i)scanf("%d",&a[i].v),a[i].id=i;
sort(a+1,a+1+n,cmpv);
for(int i=1;i<=n;++i){
pre[a[i].id]=-1;
if(i!=1&&a[i].v==a[i-1].v)pre[a[i].id]=a[i-1].id;
}
sort(a+1,a+1+n,cmpid);
memset(c,0,sizeof(c));
scanf("%d",&q);
for(int i=0;i<q;++i)scanf("%d%d",&p[i].l,&p[i].r),p[i].id=i;
sort(p,p+q);
for(int i=0,cur=1;i<q;++i){
for(;cur<=p[i].r;++cur){
if(pre[cur]!=-1)add(pre[cur],-a[cur].v);
add(cur,a[cur].v);
}
ret[p[i].id]=ask(p[i].r)-ask(p[i].l-1);
}
for(int i=0;i<q;++i)printf("%I64d\n",ret[i]);
}
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: