zoukankan      html  css  js  c++  java
  • 给定区间求不同数的个数

                                              Different Integers

    Given a sequence of integers a1, a2, ..., an and q pairs of integers (l1, r1), (l2, r2), ..., (lq, rq), find count(l1, r1), count(l2, r2), ..., count(lq, rq) where count(i, j) is the number of different integers among a1, a2, ..., ai, aj, aj + 1, ..., an.

    输入描述:

    The input consists of several test cases and is terminated by end-of-file.
    The first line of each test cases contains two integers n and q.
    The second line contains n integers a1,a2,.....an.

    The i-th of the following q lines contains two integers l and r.

    输出描述:

    For each test case, print q integers which denote the result.

     

    输入

    3 2
    1 2 1
    1 2
    1 3
    4 1
    1 2 3 4
    1 3

    输出

    2
    1
    3

    备注:

    * 1 ≤ n, q ≤ 100000
    * 1 ≤ ai ≤ n
    * 1 ≤ l,r≤ n
    * The number of test cases does not exceed 10.

    把序列加长一倍,就变成了连续区间求不同数的个数。
    我们遍历整个序列,当有相同的数时,保留后一个数,删除前一个数,这样当遍历到第x个数的时候,可能的序列就变为了 a1 , a2 , * , *, a5, a6 ......ax;
    其中*代表这个数已经被删除了
    这样若要求区间[i,x]内不同数的个数,直接就是从i到x内不为*的数的个数,若把存在的数权值改为1,那么答案也就是sum(x)-sum(i-1),这样就可以考虑用树状数组来优化,注意这个性质求的区间其右端点必须是x。
    要注意遍历序列之前要先把查询离线存起来,然后对r进行升序排列,保证按顺序遍历序列的时候,查询区间右端点是依次出现的。
    #include<bits/stdc++.h>
    #define N 200500
    using namespace std;
    int last[N],team[N];
    int c[N];
    int Ans[N];
     
    void updata(int x,int v)
    {
        while(x<N)
        {
            c[x]+=v;
            x+=x&(-x);
        }
    }
     
    int Sum(int x)
    {
        int ans=0;
        while(x>0)
        {
            ans+=c[x];
            x-=x&(-x);
        }
        return ans;
     
    }
     
     
     
    typedef struct
    {
        int l,r,ans,index;
     
    }ss;
     
    ss qu[N];
     
    int cmp(ss a,ss b)
    {
        return a.r<b.r;
    }
     
     
    int main()
    {
       int n,q,sum;
     
       while(scanf("%d %d",&n,&q)==2)
       {
           memset(last,0,sizeof(last));
           memset(c,0,sizeof(c));
           sum=0;
     
           for(int i=1;i<=n;i++)
           {
               scanf("%d",&team[i]);
               team[i+n]=team[i];
           }
     
            for(int i=1;i<=q;i++)scanf("%d %d",&qu[i].r,&qu[i].l),qu[i].index=i,qu[i].r+=n;
            sort(qu+1,qu+1+q,cmp);
     
          //  for(int i=1;i<=q;i++)printf("%d %d
    ",qu[i].l,qu[i].r);
     
            int c1=1;
            for(int i=1;i<=q;i++)
            {
                for(int j=c1;j<=qu[i].r;j++)
                {
                    if(last[team[j]]==0)
                    {
                        updata(j,1);
                        last[team[j]]=j;
     
                    }
                    else
                    {
                        updata(j,1);
                        updata(last[team[j]],-1);
                        last[team[j]]=j;
     
                    }
     
                }
                c1=qu[i].r+1;
     
                Ans[qu[i].index]=Sum(qu[i].r)-Sum(qu[i].l-1);
     
     
            }
     
        for(int i=1;i<=q;i++)printf("%d
    ",Ans[i]);
     
       }
     
        return 0;
    }
    View Code


  • 相关阅读:
    poj1006生理周期(中国剩余定理)
    Sort the Array
    pojBuy Tickets2828线段树或者树状数组(队列中倒序插队)
    poj 2187 Beauty Contest(凸包求解多节点的之间的最大距离)
    将数据转化成字符串时:用字符串的链接 还是 StringBuilder
    poj 2031Building a Space Station(几何判断+Kruskal最小生成树)
    java中同步嵌套引起的死锁事例代码
    poj 1905Expanding Rods
    (单例设计模式中)懒汉式与饿汉式在多线程中的不同
    HDU 1024Max Sum Plus Plus(最大m字段和)
  • 原文地址:https://www.cnblogs.com/tian-luo/p/9338938.html
Copyright © 2011-2022 走看看