Turing Tree
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 6568 Accepted Submission(s): 2345
Problem Description
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.
Input
The first line is an integer T (1 ≤ T ≤ 10), indecating the number of testcases below.
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).
Output
For each Query, print the sum of distinct values of the specified subsequence in one line.
Sample Input
2 3 1 1 4 2 1 2 2 3 5 1 1 2 1 3 3 1 5 2 4 3 5
Sample Output
1 5 6 3 6
Author
3xian@GDUT
Source
HDOJ Monthly Contest – 2010.03.06
Recommend
lcy | We have carefully selected several similar problems for you: 1542 3397 1698 1540 1255
Statistic | Submit | Discuss | Note
Home | Top | Hangzhou Dianzi University Online Judge 3.0 Copyright © 2005-2018 HDU ACM Team. All Rights Reserved. Designer & Developer : Wang Rongtao LinLe GaoJie GanLu Total 0.000000(s) query 5, Server time : 2018-07-20 14:14:20, Gzip enabled | Administration |
题意:求区间内不同数的和。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=30005;
const int maxq=100005;
map<ll,ll>mp;
struct node
{
ll l,r,id;//输入查询的区间
//id记录的是每个查询的次序,目的是在对查询区间排序后,能按原来的查询顺序输出结果
};
node q[maxq];
bool cmp(node a,node b)
{
return a.r<b.r;
}
ll c[maxn];
int n;
int lowbit(int x)
{
return x&(-x);
}
ll sum(int x)
//int query(int x)
{
ll res=0;
while(x)
{
res+=c[x];
x-=lowbit(x);
}
return res;
}
void add(int x,ll val)
{
while(x<=n)
{
c[x]+=val;
x+=lowbit(x);
}
}
ll a[maxn];
ll ans[maxq];
int main()
{
int i,j,cur,Q,t;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
mp.clear();
memset(c,0,sizeof(c));
for(i=1;i<=n;i++)
scanf("%lld",&a[i]);
scanf("%d",&Q);
for(i=1;i<=Q;i++)
{
scanf("%lld%lld",&q[i].l,&q[i].r);
q[i].id=i;
}
sort(q+1,q+1+Q,cmp);//按右端点排序
cur=1;
for(i=1;i<=Q;i++)
{
for(j=cur;j<=q[i].r;j++)
{
if(mp.find(a[j])!=mp.end())//在前面出现过
{
add(mp[a[j]],-a[j]);
}
mp[a[j]]=j;
add(j,a[j]);
}
cur=q[i].r+1;
ans[q[i].id]=sum(q[i].r)-sum(q[i].l-1);
}
//一开始cur=1,是1到q[1].r,先对这个小区间操作,然后cur=q[1].r+1
//是q[1].r到q[2].r,继续下去
for(i=1;i<=Q;i++)
//printf("%lld\n",ans[i]);
cout<<ans[i]<<endl;
}
}