zoukankan      html  css  js  c++  java
  • hdu 3333 Turing Tree

    Turing Tree

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


    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

    //这题的做法是先离散化,然后把Q按右边端点进行升序排序

    //这是把数据一个个插入、遇到以前出现了的数字,就删除原来的位置的值,在新位置插入

    //这样做法的正确性和按Q的右端点排序有关

    //遇到坐标和Q右端点相等时就可以完成query,并且保存

    //最后按输入小标排序,并输出结果,树状数组比线段树快些

    #include <iostream>
    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    #define N 33334//我开始把这写成3333,然后后面Q的区间数组有N*3
    #define lson l,m,k<<1  //我很二的以为这样已经超过10W了,然后纠结了一下午,
    #define rson m+1,r,k<<1|1  //抓狂、、、这题好多3,真被伤到了
    using namespace std;
    __int64 st[N<<2];
    int rc[N],sv[N],rci[N];
    bool hash[N];
    struct node
    {
        int i,j;
        int index;
        __int64 ans;
        bool operator<(const node&a)const
        {
            return j<a.j;
        }
    };
    node interval[N*3];
    int n;
    int bf(int &val)
    {
       int l=1,r=n,m;
       while(l<=r)
       {
           m=(l+r)>>1;
           if(rc[m]>val) r=m-1;
           else if(rc[m]<val) l=m+1;
           else return m;
       }
    }
    bool cmp(const node&a,const node&b)
    {
        return a.index<b.index;
    }
    void build(int l,int r,int k)
    {
        st[k]=0;
        if(l==r)
         return;
        int m=(l+r)>>1;
        build(lson);
        build(rson);
    }
    void up(int &k)
    {
        st[k]=st[k<<1]+st[k<<1|1];
    }
    int flag;
    void update(int index,int l,int r,int k)
    {
        if(l==r)
        {
            st[k]=flag;//printf(" flag%.lf  ",flag);
            return;
        }
        int m=(l+r)>>1;
        if(index<=m) update(index,lson);
        else update(index,rson);
        up(k);
    }
    double query(int &L,int &R,int l,int r,int k)
    {
        if(L<=l&&R>=r)
        {
            return st[k];
        }
        int m=(l+r)>>1;
        double t1=0,t2=0;
        if(L<=m) t1=query(L,R,lson);
        if(R>m)  t2=query(L,R,rson);
        return t1+t2;
    }
    int main()
    {
        int T;
        int Q;
        int i,k,rcn;
        scanf("%d",&T);
        while(T--)
        {
            scanf("%d",&n);rcn=n;
            for(i=1;i<=n;i++)
              scanf("%d",&rc[i]),sv[i]=rc[i],hash[i]=0;
            sort(rc+1,rc+n+1);
            for(k=1,i=2;i<=n;i++)
             if(rc[i]!=rc[k])
              rc[++k]=rc[i];
            n=k;

            scanf("%d",&Q);
            for(i=0;i<Q;i++)
              {
                  scanf("%d%d",&interval[i].i,&interval[i].j);
                  interval[i].index=i;
              }
            sort(interval,interval+Q);
            //interval[Q].j=-1;

            build(1,rcn,1);
            k=0;int temp;
            for(i=1;i<=rcn;i++)
            {
              temp=bf(sv[i]);
              if(hash[temp])
              {
                  flag=0;
                  update(rci[temp],1,rcn,1);

                  flag=sv[i];
                  rci[temp]=i;
                  update(i,1,rcn,1);
              }
              else
              {
                 hash[temp]=1;

                 flag=sv[i];
                 rci[temp]=i;
                 update(i,1,rcn,1);
              }
              while(i==interval[k].j)
             {
                interval[k].ans=query(interval[k].i,interval[k].j,1,rcn,1);
                k++;
                if(k>=Q) break;
             }
             if(k>=Q) break;
            }
          sort(interval,interval+Q,cmp);
          for(i=0;i<Q;i++)
           printf("%I64d\n",interval[i].ans);
        }
        return 0;
    }

    //改用树状数组做、快了200Ms吧
    #include <iostream>
    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    #define N 33334
    using namespace std;
    struct node
    {
        int i,j;
        int index;
        __int64 ans;
        bool operator<(const node&a)const
        {
            return j<a.j;
        }
    };
    node interval[N*3];
    int n,rcn;
    __int64 c[N];
    int rc[N],sv[N],rci[N];
    int lb[N];
    bool hash[N];
    int bf(int &val)
    {
       int l=1,r=n,m;
       while(l<=r)
       {
           m=(l+r)>>1;
           if(rc[m]>val) r=m-1;
           else if(rc[m]<val) l=m+1;
           else return m;
       }
    }
    bool cmp(const node&a,const node&b)
    {
        return a.index<b.index;
    }
    void update(int index,int val)
    {
        for(;index<=rcn;index+=lb[index])
           c[index]+=val;
    }
    __int64 r_sum(int index)
    {
        __int64 sum=0;
        for(;index>0;index-=lb[index])
          sum+=c[index];
        return sum;
    }
    int main()
    {
        int T;
        int Q;
        int i,k;
        for(i=1;i<=30000;i++)lb[i]=i&(-i);
        scanf("%d",&T);
        while(T--)
        {
            scanf("%d",&n);rcn=n;
            for(i=1;i<=n;i++)
              {
                  scanf("%d",&rc[i]);
                  sv[i]=rc[i];
                  hash[i]=0;
                  c[i]=0;
              }
            sort(rc+1,rc+n+1);
            for(k=1,i=2;i<=n;i++)
             if(rc[i]!=rc[k])
              rc[++k]=rc[i];
            n=k;
            scanf("%d",&Q);
            for(i=0;i<Q;i++)
              {
                  scanf("%d%d",&interval[i].i,&interval[i].j);
                  interval[i].index=i;
              }
            sort(interval,interval+Q);
            k=0;int temp;
            for(i=1;i<=rcn;i++)
            {
              temp=bf(sv[i]);
              if(hash[temp])
              {
                  update(rci[temp],-sv[i]);
                  rci[temp]=i;
                  update(i,sv[i]);
              }
              else
              {
                 hash[temp]=1;
                 rci[temp]=i;
                 update(i,sv[i]);
              }
              while(i==interval[k].j)
             {
            interval[k].ans=r_sum(interval[k].j)-r_sum(interval[k].i-1);
                k++;
                if(k>=Q) break;
             }
             if(k>=Q) break;
            }
           sort(interval,interval+Q,cmp);
          for(i=0;i<Q;i++)
           printf("%I64d\n",interval[i].ans);
        }
        return 0;
    }


  • 相关阅读:
    GitHub 访问不顺怎么办?在线等,急
    深度解读最新版 Scrum 指南
    有奖体验 CODING 产品,iPad Pro、HHKB 键盘等超级礼包等你来!
    腾讯全资子公司 CODING 2021 届校园招聘正式开启!
    产品更新 | 「CODING 持续部署」新手体验:应用发布只需 30 秒!
    CODING 推出独立制品仓库 WePack,助力企业渐进式 DevOps 转型
    CODING DevOps 线下沙龙回顾一:DevOps 代码质量实战
    CODING 荣获「2020 DevOps 领域年度极具影响力产品」奖项
    CODING DevOps 产品认证学习计划正式启动!
    DevOps Workshop | 代码管理入门:基于代码扫描实现团队效率提升
  • 原文地址:https://www.cnblogs.com/372465774y/p/2617131.html
Copyright © 2011-2022 走看看