Necklace
Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 4604 Accepted Submission(s): 1581
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
题意:
给一串数,若干询问,每次询问一个区间内不重复数字之和。
代码:
1 /* 2 把询问的几个区间先存起来,将其按照区间右端点从小到大排序,这样当去掉某一区间内的重复值时就不会 3 影响其他区间,因为其他区间的右端点要么比他小,要么比他大,比他小的不会受影响(树状数组向上更新) 4 ,比他大的恰好也要去重。去重时利用map。 5 */ 6 #include<iostream> 7 #include<cstdio> 8 #include<map> 9 #include<cstring> 10 #include<algorithm> 11 #include<cmath> 12 const int MAXN=50005; 13 const int MAXM=200005;//MAXM,MAXN改为30005,1000005就是HDU3333题题解 14 long long A[MAXN]; 15 long long NE[MAXN]; 16 int t,n,m; 17 struct Necklace 18 { 19 int R,L,id;//区间右端点,区间左端点,序号 20 }neck[MAXM]; 21 bool cmp(Necklace a,Necklace b) 22 { 23 if(a.R==b.R) 24 return a.L<b.L; 25 else return a.R<b.R; 26 } 27 int lowbit(int x) 28 { 29 return x&(-x); 30 } 31 void add(int id,long long c) 32 { 33 while(id<=MAXN) 34 { 35 A[id]+=c; 36 id+=lowbit(id); 37 } 38 } 39 long long sum(int id) 40 { 41 long long s=0; 42 while(id>0) 43 { 44 s+=A[id]; 45 id-=lowbit(id); 46 } 47 return s; 48 } 49 using namespace std; 50 int main() 51 { 52 scanf("%d",&t); 53 while(t--) 54 { 55 scanf("%d",&n); 56 for(int i=1;i<=n;i++) 57 scanf("%lld",&NE[i]); 58 scanf("%d",&m); 59 for(int i=0;i<m;i++) 60 { 61 scanf("%d%d",&neck[i].L,&neck[i].R); 62 // if(neck[i].L>neck[i].R) 63 // swap(neck[i].L,neck[i].R); 64 neck[i].id=i; 65 } 66 sort(neck,neck+m,cmp); 67 int p=1; 68 map<int,int>mp; 69 long long ans[MAXM]; 70 memset(A,0,sizeof(A)); 71 for(int i=0;i<m;i++) 72 { 73 while(p<=neck[i].R)//小于等于区间右端点的 74 { 75 long long x=NE[p]; 76 if(mp[x]!=0)//如果前面出现过此X值就减去旧的加上新的 77 add(mp[x],-x); 78 add(p,x); 79 mp[x]=p; 80 p++; 81 } 82 ans[neck[i].id]=sum(neck[i].R)-sum(neck[i].L-1); 83 } 84 for(int i=0;i<m;i++) 85 printf("%lld\n",ans[i]); 86 } 87 return 0; 88 }