莫队算法 (利于复习)

思想:

   在队列里通过l,r 更新区间的答案;

   不过要分 根号n 的版块 进行(特殊)排序;

  代码:

struct dian{
	int l,r,pos(版块),id;
	bool operator <(const dian &t)const   //特殊排序
	{
		if(pos==t.pos) return r<t.r;
		return l<t.l;
	}
}p[M];

 例题 :

给定n个数字序列a 1,a 2,...,a n和许多d查询。d查询是一对(i,j)(1≤i≤j≤n)。对于每个d查询(i,j),您必须返回子序列a i,ai + 1,...,a j中不同元素的数量。

输入项

  • 第1行:n(1≤n≤30000)。
  • 第2行:n个一个1,一个2,...,A Ñ(1≤一个 ≤10 6)。
  • 第3行:d查询的数量q(1≤q≤200000)。
  • 在接下来的q行中,每行包含2个代表d查询的数字i,j(1≤i≤j≤n)。

输出量

  • 对于每个d查询(i,j),在一行中打印子序列a i,a i + 1,...,j j中不同元素的数量。

     

输入项
5
1 1 2 1 3
3
1 5
2 4
3 5

输出量
3
2
3 

代码:
#include <bits/stdc++.h>
using namespace std;
const long long M=2000000;
struct dian{
    long long  l,r,pos,id,ans;
      bool operator <(const dian &t)const 
     {
         if(pos==t.pos) return r<t.r;
         return l<t.l;
     }
}p[M];
long long n,m,val[M],cent[M],trmp,ans2[M];
long long main(){
    scanf("%d",&n);
    for(register long long i=1;i<=n;i++)
    {
       scanf("%d",&val[i]);
    }
    long long d=long long(0.5+sqrt(n));
//    cout<<d<<endl;
    scanf("%d",&m);
    for(register long long i=1;i<=m;i++)
    {
        long long a,b;
        scanf("%d%d",&a,&b);
        p[i].pos=a/d;
        p[i].id=i;
        p[i].l=a;
        p[i].r=b;
    }
    sort(p+1,p+m+1);
//    cout<<"yes"<<endl;
    for(register long long i=p[1].l;i<=p[1].r;i++)
    {
        cent[val[i]]++;
        if(cent[val[i]]==1)
        p[1].ans++;
    }
//    cout<<"yes"<<endl;
    ans2[p[1].id]=p[1].ans;
    for(register long long i=2;i<=m;i++)
    {
        trmp=p[i-1].ans;
        long long l=p[i-1].l;
        long long r=p[i-1].r;
        while(l<p[i].l)
        {
            cent[val[l]]--;
            if(cent[val[l]]==0) //
            trmp--;
            l++;
        }
        while(l>p[i].l)
        {
            l--;
            cent[val[l]]++;
            if(cent[val[l]]==1)
            trmp++;
        }
        while(r<p[i].r)
        {
            r++;
            cent[val[r]]++;
            if(cent[val[r]]==1)
            trmp++;
        }
        while(r>p[i].r)
        {
            cent[val[r]]--;
            if(cent[val[r]]==0)
            trmp--;
            r--;
        }
        p[i].ans=trmp;
        ans2[p[i].id]=trmp;
    }
//    cout<<"yes"<<endl;
    for(register long long i=1;i<=m;i++)
    {
        prlong longf("%d\n",ans2[i]);
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/Lamboofhome/p/11709877.html
今日推荐