[ 莫队 树状数组 ] [ AHOI2013 ] BZOJ3236

%%%PBS

大佬教我莫队cmp函数更快的写法。

#include
using namespace std;
inline char nc(){
    static char buf[100000],*p1=buf,*p2=buf;
    return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
inline void Read(int& x){
    char c=nc();
    for(;c<'0'||c>'9';c=nc());
    for(x=0;c>='0'&&c<='9';x=(x<<3)+(x<<1)+c-48,c=nc());
}
#define N 100010
#define M 1000010
struct Node{
    int l,r,a,b,f;
}q[M];
int i,j,k,n,m,p,b[N],a[N],c[2][N],s,Res,Ans[2][M];
int L,R,f[N];
inline bool Cmp(Node x,Node y){
    return b[x.l]y.l]||(b[x.l]==b[y.l]&&(b[x.l]&1?x.r<y.r:x.r>y.r));
}
inline void Update(int x,int y,bool d){
    for(;x<=n;x+=x&-x)c[d][x]+=y;
}
inline int Query(int x,bool d){
    int Ans=0;
    for(;x;x-=x&-x)Ans+=c[d][x];
    return Ans;
}
inline void Add(int x){
    if(!f[x]){
        f[x]=1;
        Update(x,1,1);
    }else f[x]++;
    Update(x,1,0);
}
inline void Del(int x){
    if(!(--f[x])){
        Update(x,-1,1);
    }
    Update(x,-1,0);
}
int main(){
    Read(n);Read(m);s=sqrt(n);
    for(i=1;i<=n;i++)Read(a[i]);
    for(i=1;i<=m;i++)Read(q[i].l),Read(q[i].r),Read(q[i].a),Read(q[i].b),q[i].f=i;
    for(i=1;i<=n;i++)b[i]=(i-1)/s+1;
    sort(q+1,q+m+1,Cmp);
    for(i=1,L=1,R=0;i<=m;i++){
        while(R<q[i].r)Add(a[++R]);
        while(L>q[i].l)Add(a[--L]);
        while(R>q[i].r)Del(a[R--]);
        while(L<q[i].l)Del(a[L++]);
        for(j=0;j<2;j++)
        Ans[j][q[i].f]=Query(q[i].b,j)-Query(q[i].a-1,j);
    }
    for(i=1;i<=m;i++)printf("%d %d\n",Ans[0][i],Ans[1][i]);
    return 0;
}

你可能感兴趣的:(莫队,树状数组)