• hdu 3333(树状数组 + 离线操作)


    Turing Tree

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


    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
     
    Recommend
    lcy   |   We have carefully selected several similar problems for you:  1542 3397 1394 1540 1255 

    题目描述: 求给定一个序列中某段子区间的相异数的和。

    要求相异数的和,那就把相同的数去掉就行,可是由于查询的区间不确定,假设要查被删数之前包含被删数的区间的和,就不好办了。

    所以我们首先读入所有的查询,然后在建立树状数组的过程中可以一次回答以i结尾的数之前的所有查询,如果有重复的就删掉,

    因为比i小的以它结尾所有的查询都存下。由于要按顺序输出它的结果,所以我们给每个查询操作编号,又由于要从小到大回答以i结尾

    的所有查询,所以我们采用一个结构体,成员变量分别是L,R,ID;以R来对结构体排序,将结果存入map<int,int > s;

    s[ID]中,采用二维数组浪费空间,采用map进行映射.

    最后一点要注意的是c数组的大小要是n的最大值×4;

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <vector>
    #include <algorithm>
    #include <map>
    #define maxn 55555*4
    #define LL long long
    #define inf 0x3f3f3f3f3f3f3f3f3f3f
    #define lowbit(x)   x & (-x)
    using namespace std;
    //int visit[maxn];
    //int VISIT[maxn];
    map <LL,LL >  visit;
    map <LL ,LL > VISIT;
    LL  A[maxn];
    int n,cnt;
    struct node
    {
        int L,R,id;
    };
    node Q[maxn];
    LL c[maxn];
    LL ans[maxn];
    void init()
    {
        memset(c,0,sizeof(c));
        //memset(visit,0,sizeof(visit));
         //memset(VISIT,0,sizeof(VISIT));
        visit.clear();
        VISIT.clear();
        cnt=0;
    }
    LL sum(int x)
    {
        LL ret=0;
        while(x>0)
        {
          ret+=c[x];
          x-=(x&(-x) );
        }
        return ret;
    }
    void add(int x,LL d)
    {
       while(x<=n)
       {
          c[x]+=d;
          x+=(x& (-x) );
       }
    }
    void solve()
    {
        for(int i=1;i<=n;i++)
        {
            if(visit[A[i]]!=0)
            {
                add(visit[A[i]],-A[i]);
            }
            visit[A[i]]=i;
            add(i,A[i]);
            if(VISIT[i]!=0)
            {
                for(int j=1;j<=VISIT[i];j++)
                {
                    cnt++;
                    ans[Q[cnt].id]=sum(Q[cnt].R)-sum(Q[cnt].L-1);
                    //printf("%lld
    ",ans[Q[cnt].id]);
                }
            }
        }
    }
    bool cmp(node a,node b)
    {
      if(a.R==b.R)
         return a.L<b.L;
       else
        return a.R<b.R;
    }
    int main()
    {
    //freopen("test.txt","r",stdin);
        int t,q;
        scanf("%d",&t);
        while(t--)
        {
             init();
             scanf("%d",&n);
             for(int i=1;i<=n;i++)
                scanf("%lld",&A[i]);
             scanf("%d",&q);
             for(int i=1;i<=q;i++)
             {
                 scanf("%d%d",&Q[i].L,&Q[i].R);
                 Q[i].id=i;
                 // printf("%d
    ",Q[i].id);
                 ++VISIT[Q[i].R];
             }
             sort(Q+1,Q+q+1,cmp);
    
            /* for(int i=1;i<=q;i++)
             {
                printf("%d
    ",Q[i].id);
             }*/
             solve();
             for(int i=1;i<=q;i++)
             {
                printf("%lld
    ",ans[i]);
             }
    
        }
        return 0;
    }
  • 相关阅读:
    20180925-5 代码规范,结对要求
    20180925-6 四则运算试题生成
    20180925-7 规格说明书-吉林市2日游
    第二周例行报告
    第二周博客作业
    【杨老师粉丝群】第一周立会报告第四次
    20180925-1 每周例行报告
    规格说明书——吉林市两日游
    效能分析
    四则运算试题生成
  • 原文地址:https://www.cnblogs.com/xianbin7/p/4522742.html
Copyright © 2020-2023  润新知