莫队
哈。。。。一开始没注意用树状数组。。。妥妥的TTTTT
然后才改了分块
lowbit(T)
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
const
int maxn=100001;
int Pos[maxn];
int T[maxn*2];
int n,m;
inline int lowbit(int x){return x&-x;}
inline void add(int x)
{for(int i=x;i<=n*2;i+=lowbit(i))T[i]++;}
inline void del(int x)
{for(int i=x;i<=n*2;i+=lowbit(i))T[i]--;}
inline int query(int x)
{int ans=0;for(int i=x;i;i^=lowbit(i))ans+=T[i];return ans;}
struct Que
{int x,a,b,y,id,ans;inline friend bool operator <(Que a,Que b){return a.id<b.id;}};
inline bool cmp(Que a,Que b)
{return Pos[a.x]^Pos[b.x]?Pos[a.x]<Pos[b.x]:a.y<b.y;}
char c;
inline void read(int &a)
{
a=0;do c=getchar();while(c<'0'||c>'9');
while(c<='9'&&c>='0')a=(a<<3)+(a<<1)+c-'0',c=getchar();
}
Que Line[maxn*10];
int s[maxn];
int con[maxn];
int main()
{
int i,j,k,l;
read(n),read(m);
int size=sqrt(n);
for(i=1;i<=n;i++)
Pos[i]=i/size,read(s[i]);
for(i=1;i<=m;i++)
read(Line[i].x),
read(Line[i].y),
read(Line[i].a),
read(Line[i].b),
Line[i].id=i;
sort(Line+1,Line+1+m,cmp);
l=1;int r=0;
for(i=1;i<=m;i++)
{
Que tp=Line[i];
while(r<tp.y)
{++r;if(!con[s[r]])add(s[r]);con[s[r]]++;}
while(l>tp.x)
{l--;if(!con[s[l]])add(s[l]);con[s[l]]++;}
while(l<tp.x)
{con[s[l]]--;if(!con[s[l]])del(s[l]);l++;}
while(r>tp.y)
{con[s[r]]--;if(!con[s[r]])del(s[r]);r--;}
Line[i].ans=query(tp.b)-query(tp.a-1);
}
sort(Line+1,Line+1+m);
for(int i=1;i<=m;i++)
printf("%d\n",Line[i].ans);
return 0;
}
分块
#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
const
int maxn=100001;
int Pos[maxn];
int n,m;
struct Que
{int x,a,b,y,id,ans;inline friend bool operator <(Que a,Que b){return a.id<b.id;}};
inline bool cmp(Que a,Que b)
{return Pos[a.x]^Pos[b.x]?Pos[a.x]<Pos[b.x]:a.y<b.y;}
char c;
inline void read(int &a)
{
a=0;do c=getchar();while(c<'0'||c>'9');
while(c<='9'&&c>='0')a=(a<<3)+(a<<1)+c-'0',c=getchar();
}
Que Line[maxn*10];
int s[maxn];
int con[maxn];
int size;
int a[400];
inline void del(int x)
{a[x/size]--;}
inline void add(int x)
{a[x/size]++;}
inline int query(int x,int y)
{
int ans=0;
int i,mp=(x/size+1)*size;
if(Pos[x]^Pos[y])
{
if(!(Pos[x]^Pos[x-1]))
for(i=x;i<mp;i++)
ans+=con[i]==0?0:1;
for(i=Pos[x]+(Pos[x]^Pos[x-1]?0:1);i<=Pos[y];i++)
ans+=a[i];
for(i=min((Pos[y]+1)*size-1,n);i>y;i--)
ans-=con[i]==0?0:1;
return ans;
}
for(i=x;i<=y;i++)
ans+=con[i]==0?0:1;
return ans;
}
int main()
{
int i,j,k,l;
read(n),read(m);
size=sqrt(n);
Pos[0]=0;
for(i=1;i<=n;i++)
Pos[i]=i/size,read(s[i]);
for(i=1;i<=m;i++)
read(Line[i].x),
read(Line[i].y),
read(Line[i].a),
read(Line[i].b),
Line[i].id=i;
sort(Line+1,Line+1+m,cmp);
l=1;int r=0;
for(i=1;i<=m;i++)
{
Que tp=Line[i];
while(r<tp.y)
{++r;if(!con[s[r]])add(s[r]);con[s[r]]++;}
while(l>tp.x)
{l--;if(!con[s[l]])add(s[l]);con[s[l]]++;}
while(l<tp.x)
{con[s[l]]--;if(!con[s[l]])del(s[l]);l++;}
while(r>tp.y)
{con[s[r]]--;if(!con[s[r]])del(s[r]);r--;}
Line[i].ans=query(tp.a,tp.b);
}
sort(Line+1,Line+1+m);
for(int i=1;i<=m;i++)
printf("%d\n",Line[i].ans);
return 0;
}