zoukankan      html  css  js  c++  java
  • BZOJ_3809_Gty的二逼妹子序列 && BZOJ_3236_[Ahoi2013]作业 _莫队+分块

    BZOJ_3809_Gty的二逼妹子序列 && BZOJ_3236_[Ahoi2013]作业 _莫队+分块

    Description

    Autumn和Bakser又在研究Gty的妹子序列了!但他们遇到了一个难题。
    对于一段妹子们,他们想让你帮忙求出这之内美丽度∈[a,b]的妹子的美丽度的种类数。
    为了方便,我们规定妹子们的美丽度全都在[1,n]中。
    给定一个长度为n(1<=n<=100000)的正整数序列s(1<=si<=n),对于m(1<=m<=1000000)次询问“l,r,a,b”,每次输出sl...sr中,权值∈[a,b]的权值的种类数。

    Input

    第一行包括两个整数n,m(1<=n<=100000,1<=m<=1000000),表示数列s中的元素数和询问数。
    第二行包括n个整数s1...sn(1<=si<=n)。
    接下来m行,每行包括4个整数l,r,a,b(1<=l<=r<=n,1<=a<=b<=n),意义见题目描述。
    保证涉及的所有数在C++的int内。
    保证输入合法。

    Output

    对每个询问,单独输出一行,表示sl...sr中权值∈[a,b]的权值的种类数。

    Sample Input

    10 10
    4 4 5 1 4 1 5 1 2 1
    5 9 1 2
    3 4 7 9
    4 4 2 5
    2 3 4 7
    5 10 4 4
    3 9 1 1
    1 4 5 9
    8 9 3 3
    2 2 1 6
    8 9 1 4

    Sample Output

    2
    0
    0
    2
    1
    1
    1
    0
    1
    2

    HINT

    样例的部分解释:
    5 9 1 2
    子序列为4 1 5 1 2
    在[1,2]里的权值有1,1,2,有2种,因此答案为2。
    3 4 7 9
    子序列为5 1
    在[7,9]里的权值有5,有1种,因此答案为1。
    4 4 2 5
    子序列为1
    没有权值在[2,5]中的,因此答案为0。
    2 3 4 7
    子序列为4 5
    权值在[4,7]中的有4,5,因此答案为2。
    建议使用输入/输出优化。
     

    分析:
    经典的莫队练习题。
    可以用树状数组修改,但因为修改和查询复杂度都是$O(logn)$,修改次数为$O(nsqrt m)$,查询次数$O(m)$,总时间复杂度$O(nsqrt m logn)$。
    如果把值域分块的话修改的复杂度$O(1)$,查询复杂度$O(sqrt n)$,总时间复杂度$O(nsqrt m)$。
    把询问像莫队那么搞,然后把值域分块,每个块维护块内答案,找答案时在$a hicksim b$ 的块里面找答案。
     
    代码(3809):
    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    #include <math.h>
    using namespace std;
    char nc() {
        static char buf[100000],*p1,*p2;
        return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
    }
    inline int rd() {
        register int x=0;
        register char s=nc();
        while(s<'0'||s>'9')s=nc();
        while(s>='0'&&s<='9')x=(x<<3)+(x<<1)+s-'0',s=nc();
        return x;
    }
    #define N 100001
    int n,m,c[N],pos[N],L[1050],R[1050],size,block,ansblo[1050],h[N],ans[N*10];
    struct A {
        int l,r,a,b,id;
    }q[N*10];
    bool cmp(const A &x,const A &y) {
        if(pos[x.l]!=pos[y.l]) return x.l<y.l;
        return x.r<y.r;
    }
    int query(int l,int r) {
        int p=pos[l],q=pos[r],ans=0,i;
        if(p==q) {
            for(i=l;i<=r;i++) {
                if(h[i]) ans++;
            }
            return ans;
        }   
        for(i=p+1;i<q;i++) {
            ans+=ansblo[i];
        }
        for(i=l;i<=R[p];i++) {
            if(h[i]) ans++;
        }
        for(i=L[q];i<=r;i++) {
            if(h[i]) ans++;
        }
        return ans;
    }
    void del(int x) {
        h[x]--;
        if(h[x]==0) ansblo[pos[x]]--;
    }
    void add(int x) {
        h[x]++;
        if(h[x]==1) ansblo[pos[x]]++;
    }
    void solve() {
        int l=1,r=0,i;
        for(i=1;i<=m;i++) {
            while(l<q[i].l) del(c[l]),l++;
            while(r>q[i].r) del(c[r]),r--;
            while(l>q[i].l) l--,add(c[l]);
            while(r<q[i].r) r++,add(c[r]);
            ans[q[i].id]=query(q[i].a,q[i].b);
        }
    }
    int main() {
        n=rd(); m=rd();
        int i,j,size=sqrt(n);
        block=n/size;
        for(i=1;i<=block;i++) {
            L[i]=R[i-1]+1; R[i]=size*i;
            for(j=L[i];j<=R[i];j++) {
                c[j]=rd(); pos[j]=i;
            }
        }
        if(R[block]!=n) {
            block++; L[block]=R[block-1]+1; R[block]=n;
            for(i=L[block];i<=n;i++) {
                c[i]=rd(); pos[i]=block;
            }
        }
        for(i=1;i<=m;i++) {
            q[i].l=rd(); q[i].r=rd(); q[i].a=rd(); q[i].b=rd();
            q[i].id=i;
        }
        sort(q+1,q+m+1,cmp);
        solve();
        for(i=1;i<=m;i++) {
            printf("%d
    ",ans[i]);
        }
    }
    
    

    代码(3263):

    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    #include <math.h>
    using namespace std;
    char nc() {
    	static char buf[100000],*p1,*p2;
    	return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
    }
    inline int rd() {
    	register int x=0;
    	register char s=nc();
    	while(s<'0'||s>'9')s=nc();
    	while(s>='0'&&s<='9')x=(x<<3)+(x<<1)+s-'0',s=nc();
    	return x;
    }
    #define N 100001
    int n,m,c[N],pos[N],L[1050],R[1050],size,block,ansblo[1050],h[N],ans[N*10],ans1[N*10],ansblo1[1050];
    struct A {
    	int l,r,a,b,id;
    }q[N*10];
    bool cmp(const A &x,const A &y) {
    	if(pos[x.l]!=pos[y.l]) return x.l<y.l;
    	return x.r<y.r;
    }
    int query(int l,int r) {
    	int p=pos[l],q=pos[r],ans=0,i;
    	if(p==q) {
    		for(i=l;i<=r;i++) {
    			if(h[i]) ans++;
    		}
    		return ans;
    	}	
    	for(i=p+1;i<q;i++) {
    		ans+=ansblo[i];
    	}
    	for(i=l;i<=R[p];i++) {
    		if(h[i]) ans++;
    	}
    	for(i=L[q];i<=r;i++) {
    		if(h[i]) ans++;
    	}
    	return ans;
    }
    int query1(int l,int r) {
    	int p=pos[l],q=pos[r],i,ans=0;
    	if(p==q) {
    		for(i=l;i<=r;i++) {
    			if(h[i]) ans+=h[i];
    		}
    		return ans;
    	}
    	for(i=p+1;i<q;i++) ans+=ansblo1[i];
    	for(i=l;i<=R[p];i++) if(h[i]) ans+=h[i];
    	for(i=L[q];i<=r;i++) if(h[i]) ans+=h[i];
    	return ans;
    }
    void del(int x) {
    	h[x]--;
    	if(h[x]==0) ansblo[pos[x]]--;
    	ansblo1[pos[x]]--;
    }
    void add(int x) {
    	h[x]++;
    	if(h[x]==1) ansblo[pos[x]]++;
    	ansblo1[pos[x]]++;
    }
    void solve() {
    	int l=1,r=0,i;
    	for(i=1;i<=m;i++) {
    		while(l<q[i].l) del(c[l]),l++;
    		while(r>q[i].r) del(c[r]),r--;
    		while(l>q[i].l) l--,add(c[l]);
    		while(r<q[i].r) r++,add(c[r]);
    		ans[q[i].id]=query(q[i].a,q[i].b);
    		ans1[q[i].id]=query1(q[i].a,q[i].b);
    	}
    }
    int main() {
    	n=rd(); m=rd();
    	int i,j,size=sqrt(n);
    	block=n/size;
    	for(i=1;i<=block;i++) {
    		L[i]=R[i-1]+1; R[i]=size*i;
    		for(j=L[i];j<=R[i];j++) {
    			c[j]=rd(); pos[j]=i;
    		}
    	}
    	if(R[block]!=n) {
    		block++; L[block]=R[block-1]+1; R[block]=n;
    		for(i=L[block];i<=n;i++) {
    			c[i]=rd(); pos[i]=block;
    		}
    	}
    	for(i=1;i<=m;i++) {
    		q[i].l=rd(); q[i].r=rd(); q[i].a=rd(); q[i].b=rd();
    		q[i].id=i;
    	}
    	sort(q+1,q+m+1,cmp);
    	solve();
    	for(i=1;i<=m;i++) {
    		printf("%d %d
    ",ans1[i],ans[i]);
    	}
    }
    

     

     

  • 相关阅读:
    MsSql “with”用法
    linq更新数据冲突问题解决
    sql server 查询所有的数据库名称
    不能成功加入域的问题
    系统安全之关闭那些存在隐患的高危端口
    winform窗体上的所有控件都不显示
    sql server 创建主键
    关于sql server trace的警告信息
    ASP.NET配置文件Web.config
    运行报表提示错误:Retrieving the COM class factory for component with CLSID {11BD526015B6412D80DB12BB60B8FE50}
  • 原文地址:https://www.cnblogs.com/suika/p/8890706.html
Copyright © 2011-2022 走看看