Necklace
Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 4716 Accepted Submission(s): 1618
Problem Description
Mery has a beautiful necklace. The necklace is made up of N magic balls. Each ball has a beautiful value. The balls with the same beautiful value look the same, so if two or more balls have the same beautiful value, we just count it once. We define the beautiful value of some interval [x,y] as F(x,y). F(x,y) is calculated as the sum of the beautiful value from the xth ball to the yth ball and the same value is ONLY COUNTED ONCE. For example, if the necklace is 1 1 1 2 3 1, we have F(1,3)=1, F(2,4)=3, F(2,6)=6.
Now Mery thinks the necklace is too long. She plans to take some continuous part of the necklace to build a new one. She wants to know each of the beautiful value of M continuous parts of the necklace. She will give you M intervals [L,R] (1<=L<=R<=N) and you must tell her F(L,R) of them.
Input
The first line is T(T<=10), representing the number of test cases.
For each case, the first line is a number N,1 <=N <=50000, indicating the number of the magic balls. The second line contains N non-negative integer numbers not greater 1000000, representing the beautiful value of the N balls. The third line has a number M, 1 <=M <=200000, meaning the nunber of the queries. Each of the next M lines contains L and R, the query.
Output
For each query, output a line contains an integer number, representing the result of the query.
Sample Input
2
6
1 2 3 4 3 5
3
1 2
3 5
2 6
6
1 1 1 2 3 5
3
1 1
2 4
3 5
Sample Output
3
7
14
1
3
6
Source
2011 Multi-University Training Contest 4 - Host by SDU
题意:给你n个非负数数,每个数的值不大于1000000,给你m次询问,每次询问要求你求出所给区间的区间价值,一个区间的区间价值是这个区间中所有出现过的数的和,出现过多次的只算一次。
解题思路:离线处理即可,有人可能不知道什么叫离线处理,线段树一般是给你m次询问,在线处理是指每次处理一个询问,输出结果,离线处理是指一次处理m次询问,然后依次输出。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e6 + 10;
struct interval{
int l;
int r;
int id;
bool operator < (const interval &x) const{
return r < x.r;
}
}Interval[maxn];
struct node{
int l;
int r;
ll sum;
}Node[4*maxn];
int N,M;
int pre[maxn];
ll ans[maxn];
void pushUp(int i)
{
int f = i>>1;
int lson = f<<1;
int rson = lson + 1;
Node[f].sum = Node[lson].sum + Node[rson].sum;
}
void build(int i,int l,int r)
{
Node[i].l = l;
Node[i].r = r;
Node[i].sum = 0;
if(l == r)
{
scanf("%I64d",&Node[i].sum);
pushUp(i);
return;
}
i <<= 1;
int mid = (l + r)>>1;
build(i,l,mid);
build(i + 1,mid + 1,r);
i >>= 1;
pushUp(i);
}
void update(int loc,int i)
{
if(Node[i].l == Node[i].r)
{
Node[i].sum = 0;
pushUp(i);
return;
}
int mid = (Node[i].l + Node[i].r)>>1;
int lson = i<<1;
int rson = lson + 1;
if(loc <= mid) update(loc,lson);
else update(loc,rson);
pushUp(i);
}
ll query(int i,int l,int r)
{
if(l == Node[i].l&&r == Node[i].r)
{
return Node[i].sum;
}
int lson = i<<1;
int rson = lson + 1;
if(r <= Node[lson].r) return query(lson,l,r);
else if(l >= Node[rson].l) return query(rson,l,r);
else return query(lson,l,Node[lson].r) + query(rson,Node[rson].l,r);
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d",&N);
build(1,1,N);
scanf("%d",&M);
for(int i = 1; i <= M; i++)
{
scanf("%d%d",&Interval[i].l,&Interval[i].r);
Interval[i].id = i;
}
sort(Interval + 1,Interval + M + 1);
memset(pre,-1,sizeof(pre));
for(int i = 1,j = 1; i <= N; i++)
{
ll term = query(1,i,i);
if(pre[term] != -1)
{
update(pre[term],1);
}
pre[term] = i;
while(j <= M&&Interval[j].r == i)
{
ans[Interval[j].id] = query(1,Interval[j].l,Interval[j].r);
j++;
}
}
for(int i = 1; i <= M; i++)
{
printf("%I64d\n",ans[i]);
}
}
return 0;
}