换成分块还是T了
http://vjudge.net/problem/HDU-6959
#include<bits/stdc++.h>
#define int long long
using namespace std;
int n, m, block;
struct node
{
int lt, rt, id, lx, rx;
bool operator<(const node &b)const
{
if(lx/block!=b.lx/block)return lx<b.lx;
if((lx/block)&1)
{
return rx<b.rx;
}
else
{
return rx>b.rx;
}
}
}a[200005];
int cnt[300005], A[200005], sum[200005];
int ans[200005];
int query(int x)
{
int ans=0;
for(int i=0;i<x/block;i++)
{
ans+=sum[i];
}
for(int i=(x/block)*block;i<=x;i++)
{
ans+=!(!cnt[i]);
}
return ans;
}
void update_in(int x)
{
if(!cnt[x])
{
sum[x/block]++;
}
cnt[x]++;
}
void update_out(int x)
{
--cnt[x];
if(!cnt[x])
{
sum[x/block]--;
}
}
//long long gcd(long long a, long long b) { return b ? gcd(b, a % b) : a; }
void solve()
{
cin>>n>>m;
block=sqrt(n);
for(int i=1;i<=100000;i++)
{
sum[i]=cnt[i]=0;
}
for(int i=1;i<=n;i++)
{
cin>>A[i];
++A[i];
}
for(int i=1;i<=m;i++)
{
cin>>a[i].lx>>a[i].lt>>a[i].rx>>a[i].rt;
++a[i].lt,++a[i].rt;
a[i].id=i;
}
sort(a+1,a+m+1);
for(int i=1,L=1,R=0;i<=m;i++)
{
while(L>a[i].lt)update_in(A[--L]);
while(R<a[i].rt)update_in(A[++R]);
while(L<a[i].lt)update_out(A[L++]);
while(R>a[i].rt)update_out(A[R--]);
ans[a[i].id]=query(a[i].rt)-query(a[i].lt-1);
}
for(int i=1;i<=m;i++)
{
cout<<ans[i]<<"\n";
}
}
signed main()
{
ios::sync_with_stdio(0);
int t;
for(cin>>t;t;t--)
{
solve();
}
}