zoukankan      html  css  js  c++  java
  • BZOJ.3809.Gty的二逼妹子序列(分块 莫队)

    题目链接

    /*
    25832 kb  26964 ms
    莫队+树状数组:增加/删除/查询 都是O(logn)的,总时间复杂度O(m*sqrt(n)*logn),卡不过 
    莫队+分块:这样查询虽然变成了sqrt(n),但是修改是O(1)的 
    考虑对权值进行分块 
    细节... 
    */
    #include<cmath>
    #include<cstdio>
    #include<cctype>
    #include<algorithm>
    using namespace std;
    const int N=1e5+5,M=1e6+5;
    
    int n,m,A[N],size,Ans[M],belong[N],times[N],bloans[N];
    struct Ques
    {
    	int l,r,a,b,id;
    	bool operator <(const Ques &x)const
    	{
    		return belong[l]==belong[x.l] ? r<x.r : l<x.l;
    	}
    }q[M];
    
    inline int read()
    {
    	int now=0,f=1;register char c=getchar();
    	for(;!isdigit(c);c=getchar())
    	  if(c=='-') f=-1;
    	for(;isdigit(c);now=now*10+c-'0',c=getchar());
    	return now*f;
    }
    
    int Query(int l,int r)
    {
    	int res=0,t=min(r,belong[l]*size);
    	for(int i=l;i<=t;++i)
    		if(times[i]) ++res;
    	if(belong[l]!=belong[r])
    		for(int i=(belong[r]-1)*size+1;i<=r;++i)
    			if(times[i]) ++res;
    	for(int i=belong[l]+1;i<belong[r];++i)
    		res+=bloans[i];
    	return res;
    }
    inline void Add(int p)
    {
    	if(!times[p]) ++bloans[belong[p]];
    	++times[p];
    }
    inline void Subd(int p)
    {
    	--times[p];
    	if(!times[p]) --bloans[belong[p]];
    }
    
    int main()
    {
    	n=read(),m=read();size=sqrt(n);
    	for(int i=1;i<=n;++i)
    		A[i]=read(), belong[i]=(i-1)/size+1;
    	for(int i=1;i<=m;++i)
    		q[i].l=read(), q[i].r=read(), q[i].a=read(), q[i].b=read(), q[i].id=i;
    	sort(q+1,q+1+m);
    	for(int i=1,l=1,r=0;i<=m;++i)
    	{
    		while(l<q[i].l) Subd(A[l++]);
    		while(l>q[i].l) Add(A[--l]);
    		while(r<q[i].r) Add(A[++r]);
    		while(r>q[i].r) Subd(A[r--]);
    		Ans[q[i].id]=Query(q[i].a,q[i].b);
    	}
    	for(int i=1;i<=m;++i)
    		printf("%d
    ",Ans[i]);
    
    	return 0;
    }
    

    2019.11.14:

    //2.04s	25.05MB 没以前跑得快...自闭了 
    #include <cmath>
    #include <cstdio>
    #include <cctype>
    #include <algorithm>
    #define gc() getchar()
    //#define MAXIN 500000
    //#define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++)
    typedef long long LL;
    const int N=1e5+5,M=1e6+5;
    
    int size,bel[N],val[N],bloans[N],times[N],Ans[M];
    //char IN[MAXIN],*SS=IN,*TT=IN;
    struct Queries
    {
    	int l,r,a,b,id;
    	bool operator <(const Queries &x)const
    	{
    		return bel[l]==bel[x.l]?r<x.r:l<x.l;
    	}
    }q[M];
    
    inline int read()
    {
    	int now=0;register char c=gc();
    	for(;!isdigit(c);c=gc());
    	for(;isdigit(c);now=now*10+c-48,c=gc());
    	return now;
    }
    inline void Add(int x)
    {
    	!times[x]&&(++bloans[bel[x]]), ++times[x];
    }
    inline void Subd(int x)
    {
    	--times[x], !times[x]&&(--bloans[bel[x]]);
    }
    inline int Query(int l,int r)
    {
    	int res=0;
    	for(int i=bel[l]+1; i<bel[r]; ++i) res+=bloans[i];
    	for(int i=l,t=std::min(bel[l]*size,r); i<=t; ++i) res+=(times[i]!=0);
    	if(bel[l]!=bel[r]) for(int i=(bel[r]-1)*size+1; i<=r; ++i) res+=(times[i]!=0);
    	return res;
    }
    
    int main()
    {
    	const int n=read(),m=read(),size=sqrt(n); ::size=size;
    	for(int i=1; i<=n; ++i) val[i]=read(), bel[i]=(i-1)/size+1;
    	for(int i=1; i<=m; ++i) q[i]=(Queries){read(),read(),read(),read(),i};
    	std::sort(q+1,q+1+m);
    	for(int i=1,l=1,r=0; i<=m; ++i)
    	{
    		int ln=q[i].l,rn=q[i].r;
    		while(l>ln) Add(val[--l]);
    		while(r<rn) Add(val[++r]);
    		while(l<ln) Subd(val[l++]);
    		while(r>rn) Subd(val[r--]);
    		Ans[q[i].id]=Query(q[i].a,q[i].b);
    	}
    	for(int i=1; i<=m; printf("%d
    ",Ans[i++]));
    
    	return 0;
    }
    
  • 相关阅读:
    Java大坑之Integer对象比较相等
    Spark操作算子本质-RDD的容错
    Spark集群搭建(local、standalone、yarn)
    Spark持久化策略
    SparkRDD内核
    Spark初识
    Hadoop集群初始化启动
    centos6.5安装MySQL5.7
    学习笔记-Kuaihu(仿知乎日报)
    Eclipse开发Android程序如何在手机上运行
  • 原文地址:https://www.cnblogs.com/SovietPower/p/8435070.html
Copyright © 2011-2022 走看看