BZOJ1878&&洛谷洛谷P1972[SDOI2009]HH的项链

真是麻了袋了,洛谷主席树能过BZ的TLE了,BZ的莫队能过洛谷TLE了

真是stm啊  主席树做法

莫队做法

//By AcerMo
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std; 
const int M=1e6+10;
struct Mo{int l,r,id;}e[M];
int n,m,sum=0,block;
int num[M],a[M],ans[M],bloc[M];
inline int read()
{
	int x=0;char ch=getchar();
	while (ch>'9'||ch<'0') ch=getchar();
	while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
	return x;
}
inline bool cmp(Mo x,Mo y)
{
	if (bloc[x.l]==bloc[y.l]) return x.r<y.r;
	return x.l<y.l;
}
inline void add(int x)
{
    if (++num[x]==1) sum++;
    return ;
}
inline void del(int x)
{
    if (--num[x]==0) sum--;
    return ;
}
inline void slove()
{
	int l=1,r=0;
    for (int i=1;i<=m;i++)
	{
        while (r<e[i].r) add(a[++r]);
        while (r>e[i].r) del(a[r--]);
        while (l<e[i].l) del(a[l++]);
        while (l>e[i].l) add(a[--l]);
        ans[e[i].id]=sum;
    }
    return ;
}
int main()
{
    n=read();block=sqrt(n);
    for (int i=1;i<=n;i++) a[i]=read();
    for (int i=1;i<=n;i++) bloc[i]=(i-1)/block+1;
    m=read();
    for (int i=1;i<=m;i++)
		e[i].l=read(),e[i].r=read(),e[i].id=i;
    sort(e+1,e+m+1,cmp);slove();
    for (int i=1;i<=m;i++) printf("%d\n",ans[i]);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/ACerAndAKer/article/details/81389589