HDU

来源:互联网 发布:订单管理系统java流程 编辑:程序博客网 时间:2024/06/16 05:09

Turing Tree

Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 5672    Accepted Submission(s): 2025


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
231 1 421 22 351 1 2 1 331 52 43 5
 

Sample Output
15636
 

Author
3xian@GDUT
 

Source
HDOJ Monthly Contest – 2010.03.06 
 

题意:
求区间[i,j],内所有不同的数的和。

sum(i,j) = sum(1,j) - sum(1,i)普通的求法,但是因为相同的只能算一次,所以还需要加上[1,i]区间中[i,j]区间中含有的数的和,这样一搞一下子就不会写了,看了看别人的思路,就有点会了,但是至于为什么以及在做题时能不能想到又是另一回事了。

感觉有点由繁化简的意思吧,就是把它从复杂的求法,转换成普通的求法。不过这个转换的过程还是有些难想的,然后用到的什么离线操作什么的,就有些难了。

#include<iostream>#include<string.h>#include<stdio.h>#include<map>#include<algorithm>using namespace std;#define LL long longconst LL maxn = 30010;LL A[maxn],n,T,Q,ans[maxn<<2],P[maxn<<2];map<LL,LL>mp;struct node {LL l,r,pos,ans;}q[100100];bool cmp1(node a,node b) {return a.r<b.r;}bool cmp2(node a,node b) {return a.pos<b.pos;}void updata(LL pos,LL val,LL l,LL r,LL x){    LL m = (l+r)/2;    if(l==r)    {        P[x] += val;        return;    }    if(pos<=m) updata(pos, val, l, m, x<<1);    else updata(pos, val, m+1, r, x<<1|1);    P[x] = P[x<<1] + P[x<<1|1];}LL sum(LL L,LL R,LL l,LL r,LL x){    LL ans = 0,m = (l+r)>>1;    if(L<=l&&r<=R) return P[x];    if(L<=m) ans+=sum(L, R, l, m, x<<1);    if(R>m) ans+=sum(L, R, m+1, r, x<<1|1);    return ans;}int main(){    scanf("%lld",&T);    while(T--)    {        mp.clear();        memset(P,0,sizeof P);        scanf("%lld",&n);        for(LL i=1;i<=n;i++)            scanf("%lld",&A[i]);        scanf("%lld",&Q);        for(int i=1;i<=Q;i++)            scanf("%lld%lld",&q[i].l,&q[i].r),q[i].pos = i,q[i].ans = 0;        sort(q+1,q+Q+1,cmp1);        LL cnt = 1;        for(int i=1;i<=n;i++)        {            updata(i,A[i],1,n,1);            if(mp[A[i]]) updata(mp[A[i]], -A[i], 1, n, 1);            mp[A[i]] = i;            while(q[cnt].r==i)            {                q[cnt].ans = sum(q[cnt].l,q[cnt].r,1,n,1);                cnt++;            }        }        sort(q+1,q+Q+1,cmp2);        for(int i=1;i<=Q;i++)            printf("%lld\n",q[i].ans);    }    return 0;}


原创粉丝点击