After inventing Turing Tree, 3xian always felt boring when solving problems about intervals, because Turing Tree could easily have the solution. As well, wily 3xian made lots of new problems about intervals. So, today, this sick thing happens again...
Now given a sequence of N numbers A1, A2, ..., AN and a number of Queries(i, j) (1≤i≤j≤N). For each Query(i, j), you are to caculate the sum of distinct values in the subsequence Ai, Ai+1, ..., Aj.
For each case, the input format will be like this:
* Line 1: N (1 ≤ N ≤ 30,000).
* Line 2: N integers A1, A2, ..., AN (0 ≤ Ai ≤ 1,000,000,000).
* Line 3: Q (1 ≤ Q ≤ 100,000), the number of Queries.
* Next Q lines: each line contains 2 integers i, j representing a Query (1 ≤ i ≤ j ≤ N).
2 3 1 1 4 2 1 2 2 3 5 1 1 2 1 3 3 1 5 2 4 3 5
1 5 6 3 6
题目大意就是给定区间求和,只是相同的数只能加一次,所以需要离线查询
刚刚才做了个离线查询,两篇博客几乎一样,只是这道题vis数组开不下那么大,需要离散一下
代码
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
#define ls o<<1
#define rs o<<1|1
#define lson L,mid,ls
#define rson mid+1,R,rs
#define mdzz int mid=(L+R)>>1;
int N,M;
long long tree[120005];
int s[30005];
int hashs[30005];
int vis[30005];
long long ans[100003];
struct node
{
int l,r,t;
bool operator <(const node &a)const
{
return a.r>r;
}
}q[200003];
void pushup(int o){
tree[o]=tree[ls]+tree[rs];
}
void update(int p,int L,int R,int o,int v){ //点修改
if(L==R){
tree[o]+=v;
return;
}
mdzz;
if(p<=mid) update(p,lson,v);
else update(p,rson,v);
pushup(o);
}
long long query(int l,int r,int L,int R,int o){//[l,r]区间询问
if(r>=R&&l<=L) return tree[o];
mdzz;
long long ans=0;
if(l<=mid)
ans+=query(l,r,lson);
if(r>mid)
ans+=query(l,r,rson);
return ans;
}
int f(long long a) //离散化函数,简单粗暴
{
int s=a%30002;
if(s<0)s+=30002;
while(vis[s]&&hashs[s]!=a)
s=(s+1)%30002;
hashs[s]=a;
return s;
}
int main()
{
int T;
scanf("%d",&T);
int a,b;
while(T--)
{
memset(vis,0,sizeof vis);
memset(tree,0,sizeof tree);
memset(hashs,0,sizeof hashs);
scanf("%d",&N);
for(int i=1;i<=N;i++)scanf("%d",&s[i]);
scanf("%d",&M);
for(int i=1;i<=M;i++)
{
scanf("%d%d",&q[i].l,&q[i].r);
q[i].t=i;
}
sort(q+1,q+M+1);
int p=1;
for(int i=1;i<=M;i++)
{
while(p<=q[i].r)
{
int temp=f(s[p]);
if(vis[temp])
update(vis[temp],1,N,1,-s[p]);
vis[temp]=p;
update(p,1,N,1,s[p]);
p++;
}
ans[q[i].t]=query(q[i].l,q[i].r,1,N,1);
}
for(int i=1;i<=M;i++)printf("%lld\n",ans[i]);
}
return 0;
}