您的位置:首页 > 其它

hdu 3333 Turing Tree 线段树

2014-02-22 14:00 357 查看
离线查是比较简单的,按查询的右界排序,不断加入a数组并用hash记录位置,如果某个值在前面已经出现过,删除前面那个值,这样下个查询查到这个值的时候,值就不会重复。 写的时候出现3个错误,主要还是对线段树的实现不熟吧,经常用模板的人就是这样...还有类型LL经常忘记写成int。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<map>
using namespace std;

#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
const int N=30005;
const int Q=100005;
typedef long long LL;
int n,tt,qq;
map<LL,int> hashs;
LL sum[N*4],a
,ans[Q];
struct QN{
int l,r,index;
}q[Q];
int cmp(QN a,QN b){
return a.r<b.r;
}
void build(int l,int r,int rt){
sum[rt]=0;
if(l==r) return;
int m=(l+r)/2;
build(lson);
build(rson);
}

void push_up(int rt){
sum[rt]=sum[rt*2]+sum[rt*2+1];
}

void update(int a,LL c,int l,int r,int rt){//单点更新a的值为c
if(l==r){
sum[rt]=c;//sum[l] --wa1
return;
}
int m=(l+r)/2;
if(a<=m)
update(a,c,lson);
else
update(a,c,rson);
push_up(rt);
}

LL query(int a,int b,int l,int r,int rt){
if(a<=l&&b>=r)
return sum[rt];
int m=(l+r)/2;
LL rst=0;//int -- wa3
if(a<=m)
rst+=query(a,b,lson);
if(b>m)
rst+=query(a,b,rson);
return rst;
}

void solve(){
int pos=1;
for(int i=0;i<qq;i++){
while(q[i].r>=pos){//加入a
if(hashs[a[pos]])//已经出现过
update(hashs[a[pos]],0,1,n,1);
hashs[a[pos]]=pos;
update(pos,a[pos++],1,n,1);//pos++ 建议放下面
}
ans[q[i].index]=query(q[i].l,q[i].r,1,n,1);
}
}

int main(){
for(cin>>tt;tt>0;tt--){
hashs.clear();
cin>>n;
build(1,n,1);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
cin>>qq;
for(int i=0;i<qq;i++){//按r排序,离线查
scanf("%d %d",&q[i].l,&q[i].r);
q[i].index=i;
}
sort(q,q+qq,cmp);
solve();
for(int i=0;i<qq;i++)
printf("%I64d\n",ans[i]);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: