• 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;
    }


  • 相关阅读:
    AlphaGo的前世今生(三)AlphaGo Zero: AI Revolution and Beyond
    AlphaGo的前世今生(二)AlphaGo: Countdown to AI Revolution
    AlphaGo的前世今生(一)Deep Q Network and Game Search Tree:Road to AI Revolution
    Exception starting filter [Tongweb WebSocket (JSR356) Filter
    spring boot 集成 redis 出现 “Unable to connect to localhost:6379”
    对女性友好的编程语言
    Git(1)
    js里面看一个字符串的汉字的个数
    celery使用的一些小坑和技巧(非从无到有的过程)
    永远相信美好的事情即将发生。
  • 原文地址:https://www.cnblogs.com/372465774y/p/2617131.html
Copyright © 2020-2023  润新知