zoukankan      html  css  js  c++  java
  • 洛谷P4887 第十四分块(前体)(二次离线莫队)

    题面

    传送门

    题解

    lxl大毒瘤

    我们考虑莫队,在移动端点的时候相当于我们需要快速计算一个区间内和当前数字异或和中(1)的个数为(k)的数有几个,而这个显然是可以差分的,也就是([l,r])的询问可以拆成([1,r]-[1,l-1])

    我们考虑莫队移动指针的过程,以([l,r])移动左指针到(p)为例,要减去的答案是(l)([1,r]-[1,l-1])(l+1)([1,r]-[1,l]),...,总的来说,我们我们要对于([1,r])这个前缀计算([l,p-1])的答案,并对每一个(i)计算出它和([1,i-1])的答案并做个前缀和

    对于前面的,因为前缀是固定的,我们可以在(r)上面开一个(vector),然后对于每一个(r),枚举所有的([l,p-1])暴力加上贡献。所以我们现在需要维护一个(O(n))次插入和(O(msqrt{m}))次询问的数据结构,扫描线的话可以做到(O({14choose 7}))插入和(O(1))查询,复杂度足够了

    然后是后面的,用上面那个数据结构就可以了

    //minamoto
    #include<bits/stdc++.h>
    #define R register
    #define pb push_back
    #define inline __inline__ __attribute__((always_inline))
    #define fp(i,a,b) for(R int i=(a),I=(b)+1;i<I;++i)
    #define fd(i,a,b) for(R int i=(a),I=(b)-1;i>I;--i)
    #define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
    template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;}
    template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;}
    using namespace std;
    typedef long long ll;
    char buf[1<<21],*p1=buf,*p2=buf;
    inline char getc(){return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;}
    int read(){
        R int res,f=1;R char ch;
        while((ch=getc())>'9'||ch<'0')(ch=='-')&&(f=-1);
        for(res=ch-'0';(ch=getc())>='0'&&ch<='9';res=res*10+ch-'0');
        return res*f;
    }
    char sr[1<<21],z[20];int K=-1,Z=0;
    inline void Ot(){fwrite(sr,1,K+1,stdout),K=-1;}
    void print(R ll x){
        if(K>1<<20)Ot();if(x<0)sr[++K]='-',x=-x;
        while(z[++Z]=x%10+48,x/=10);
        while(sr[++K]=z[Z],--Z);sr[++K]='
    ';
    }
    const int N=2e5+5;
    int a[N],bl[N],st[N],blo,top,n,m,k;ll s1[N],s2[N],s[N],ret[N],ans[N],res;
    struct node{
    	int l,r,id;
    	inline node(){}
    	inline node(R int li,R int ri,R int ii):l(li),r(ri),id(ii){}
    	inline bool operator <(const node &b)const{return bl[l]==bl[b.l]?r<b.r:l<b.l;}
    }q[N];vector<node>Q[N];
    int main(){
    //	freopen("testdata.in","r",stdin);
    	n=read(),m=read(),k=read(),blo=250;
    	for(R int i=0,c,x;i<16384;++i){
    		c=0;
    		for(x=i;x;x^=x&-x)++c;
    		if(c==k)st[++top]=i;
    	}
    	fp(i,1,n)a[i]=read(),bl[i]=(i-1)/blo+1;
    	fp(i,1,m)q[i].l=read(),q[i].r=read(),q[i].id=i;
    	sort(q+1,q+1+m);
    	for(R int i=1,l=q[1].r+1,r=q[1].r;i<=m;++i){
    		if(l<q[i].l)Q[r].pb(node(l,q[i].l-1,q[i].id<<1));
    		else if(l>q[i].l)Q[r].pb(node(q[i].l,l-1,q[i].id<<1));
    		l=q[i].l;
    		if(r<q[i].r)Q[l-1].pb(node(r+1,q[i].r,q[i].id<<1|1));
    		else if(r>q[i].r)Q[l-1].pb(node(q[i].r+1,r,q[i].id<<1|1));
    		r=q[i].r;
    	}
    	fp(i,1,n){
    		s1[i]=s1[i-1]+s[a[i]];
    		fp(k,1,top)++s[a[i]^st[k]];
    		s2[i]=s2[i-1]+s[a[i]];
    		for(vector<node>::iterator it=Q[i].begin();it!=Q[i].end();++it)
    			fp(k,it->l,it->r)ret[it->id]+=s[a[k]];
    	}
    	for(R int i=1,l=q[1].r+1,r=q[1].r;i<=m;++i){
    		if(l<q[i].l)res-=ret[q[i].id<<1]-s2[q[i].l-1]+s2[l-1];
    		else if(l>q[i].l)res+=ret[q[i].id<<1]-s2[l-1]+s2[q[i].l-1];
    		l=q[i].l;
    		if(r<q[i].r)res+=s1[q[i].r]-s1[r]-ret[q[i].id<<1|1];
    		else if(r>q[i].r)res-=s1[r]-s1[q[i].r]-ret[q[i].id<<1|1];
    		r=q[i].r,ans[q[i].id]=res;
    	}
    	fp(i,1,m)print(ans[i]);
    	return Ot(),0;
    }
    
  • 相关阅读:
    Nim or not Nim? hdu3032 SG值打表找规律
    Maximum 贪心
    The Super Powers
    LCM Cardinality 暴力
    Longge's problem poj2480 欧拉函数,gcd
    GCD hdu2588
    Perfect Pth Powers poj1730
    6656 Watching the Kangaroo
    yield 小用
    wpf DropDownButton 源码
  • 原文地址:https://www.cnblogs.com/bztMinamoto/p/10902194.html
Copyright © 2011-2022 走看看