• [AHOI2013]作业


    [AHOI2013]作业

    题目大意:

    给定一个长度为(n(nle10^5))的数列(A(1le A_ile n))(m(mle10^6))次询问,每次询问区间([l,r])内满足(ale A_ile b)的数有多少,去重后又有多少。

    思路:

    莫队+分块。

    时间复杂度(mathcal O(nsqrt n))

    源代码:

    #include<cmath>
    #include<cstdio>
    #include<cctype>
    #include<algorithm>
    inline int getint() {
    	register char ch;
    	while(!isdigit(ch=getchar()));
    	register int x=ch^'0';
    	while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
    	return x;
    }
    const int N=1e5+1,M=1e6;
    int n,m,block,a[N],ans0[M],ans1[M],cnt[N],sum[N],tot[N],bel[N],beg[N],end[N];
    struct Query {
    	int l,r,a,b,id;
    	bool operator < (const Query &rhs) const {
    		if(l/block==rhs.l/block) return r<rhs.r;
    		return l/block<rhs.l/block;
    	}
    };
    Query q[M];
    inline void ins(const int &x) {
    	if(!cnt[x]++) tot[bel[x]]++;
    	sum[bel[x]]++;
    }
    inline void del(const int &x) {
    	if(!--cnt[x]) tot[bel[x]]--;
    	sum[bel[x]]--;
    }
    inline std::pair<int,int> query(const int &l,const int &r) {
    	int ret0=0,ret1=0;
    	if(bel[l]==bel[r]) {
    		for(register int i=l;i<=r;i++) {
    			ret0+=cnt[i];
    			ret1+=!!cnt[i];
    		}
    		return std::make_pair(ret0,ret1);
    	}
    	for(register int i=l;i<=end[bel[l]];i++) {
    		ret0+=cnt[i];
    		ret1+=!!cnt[i];
    	}
    	for(register int i=bel[l]+1;i<bel[r];i++) {
    		ret0+=sum[i];
    		ret1+=tot[i];
    	}
    	for(register int i=beg[bel[r]];i<=r;i++) {
    		ret0+=cnt[i];
    		ret1+=!!cnt[i];
    	}
    	return std::make_pair(ret0,ret1);
    }
    int main() {
    	n=getint(),m=getint(),block=sqrt(n);
    	for(register int i=1;i<=n;i++) a[i]=getint();
    	for(register int i=0;i<m;i++) {
    		q[i].l=getint();
    		q[i].r=getint();
    		q[i].a=getint();
    		q[i].b=getint();
    		q[i].id=i;
    	}
    	std::sort(&q[0],&q[m]);
    	for(register int i=1;i<=n;i++) {
    		bel[i]=i/block;
    		if(!beg[bel[i]]) beg[bel[i]]=i;
    		end[bel[i]]=i;
    	}
    	for(register int i=0,l=1,r=0;i<m;i++) {
    		while(r<q[i].r) ins(a[++r]);
    		while(r>q[i].r) del(a[r--]);
    		while(l>q[i].l) ins(a[--l]);
    		while(l<q[i].l) del(a[l++]);
    		const std::pair<int,int> p=query(q[i].a,q[i].b);
    		ans0[q[i].id]=p.first;
    		ans1[q[i].id]=p.second;
    	}
    	for(register int i=0;i<m;i++) {
    		printf("%d %d
    ",ans0[i],ans1[i]);
    	}
    	return 0;
    }
    
  • 相关阅读:
    vb.net EXCEL进程问题
    VB.NET 中使用正则表达式
    改变鼠标状态
    举证信息表,语言不是VB.NET 是VBA的
    初学查询时的一些东西
    删除关联错误
    对于 using ESRI.ArcGIS.Carto; 的引用。是否缺少 using 指令或程序集引用
    AxMapControl 引用问题
    堆排序:大顶堆,小顶堆
    abs()函数,fabs函数(),max()函数的区别
  • 原文地址:https://www.cnblogs.com/skylee03/p/9646192.html
Copyright © 2020-2023  润新知