zoukankan      html  css  js  c++  java
  • BZOJ3236:[AHOI2013]作业——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=3236 

    第一种做法:

    建两棵主席树分别处理两个问题。

    第一个问题水,第二个问题参考SPOJ3267/DQUERY:D-query

    但是代码量巨大,显然不能写。

    第二种做法:

    参考:https://blog.csdn.net/clover_hxy/article/details/56288794

    对询问离线莫队,然后莫队里面套值域分块。

    ……值域分块还是很好写的就不讲了。

    可以看出代码量巨短。

    (emmm果然数据结构学傻了想的第一种做法敲了十分钟果断弃了查题解。)

    (莫队还是太菜了要多练。)

    #include<stack>
    #include<queue>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    const int N=1e5+5;
    const int M=1e6+5;
    inline int read(){
        int x=0,w=1;char ch=0;
        while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
        return x*w;
    }
    struct data{
        int pos,l,r,a,b;
    }q[M];
    int a[N],cnt[N],ans[M][2],v[N],num[N],s,n,m;
    inline int bel(int x){return (x-1)/s+1;}
    inline bool cmp(data a,data b){
        return bel(a.l)==bel(b.l)?a.r<b.r:a.l<b.l;
    }
    inline void add(int k){
        if(!cnt[k])v[bel(k)]++;
        cnt[k]++;num[bel(k)]++;
    }
    inline void del(int k){
        cnt[k]--;num[bel(k)]--;
        if(!cnt[k])v[bel(k)]--;
    }
    void query(int pos,int l,int r){
        if(bel(l)==bel(r)){
        for(int i=l;i<=r;i++){
            if(cnt[i])ans[pos][1]++,ans[pos][0]+=cnt[i];
        }
        return;
        }
        for(int i=l;i<=bel(l)*s;i++)
        if(cnt[i])ans[pos][1]++,ans[pos][0]+=cnt[i];
        for(int i=(bel(r)-1)*s+1;i<=r;i++)
        if(cnt[i])ans[pos][1]++,ans[pos][0]+=cnt[i];
        for(int i=bel(l)+1;i<=bel(r)-1;i++)
        ans[pos][1]+=v[i],ans[pos][0]+=num[i];
    }
    int main(){
        n=read(),m=read();
        s=sqrt(n);
        for(int i=1;i<=n;i++)a[i]=read();
        for(int i=1;i<=m;i++){
        q[i].pos=i,q[i].l=read(),q[i].r=read();
        q[i].a=read(),q[i].b=read();
        }
        sort(q+1,q+m+1,cmp);
        int ql=1,qr=0;
        for(int i=1;i<=m;i++){
        while(ql<q[i].l)del(a[ql++]);
        while(ql>q[i].l)add(a[--ql]);
        while(qr<q[i].r)add(a[++qr]);
        while(qr>q[i].r)del(a[qr--]);
        query(q[i].pos,q[i].a,q[i].b);
        }
        for(int i=1;i<=m;i++){
        printf("%d %d
    ",ans[i][0],ans[i][1]);
        }
        return 0;
    }

    +++++++++++++++++++++++++++++++++++++++++++

    +本文作者:luyouqi233。               +

    +欢迎访问我的博客:http://www.cnblogs.com/luyouqi233/+

    +++++++++++++++++++++++++++++++++++++++++++

  • 相关阅读:
    [loj3364]植物比较
    [loj3366]嘉年华奖券
    [atARC105F]Lights Out on Connected Graph
    [atARC105D]Let's Play Nim
    [atARC058F]Lroha Loves Strings
    [loj3347]有趣的旅途
    [atAGC001F]Wide Swap
    [cf1392I]Kevin and Grid
    [loj3340]命运
    [loj3046]语言
  • 原文地址:https://www.cnblogs.com/luyouqi233/p/8707641.html
Copyright © 2011-2022 走看看