zoukankan      html  css  js  c++  java
  • [BZOJ4028][HAOI2015]公约数数列[分块+分析暴力]

    题意

    题目链接

    分析

    • 首先明确 (xor) 运算和 ( m gcd) 没有联系!

    • 注意到一个数字取 ( m gcd) 且保证每次取 ( m gcd) 值都会变小的话,最多取 (log) 次。
      比较显然,如果每次都变小的话至少都除以了因子 (2) ,变为原来的二分之一。

    • 所以考虑一个暴力分块,记录每一块的 ( m gcd) G[i]、异或和X[i]、前缀异或和。

    • 如果 ({ m gcd}(lastgcd,G[i])=lastgcd) ,那么直接在该块记录的前缀异或和中查找(frac{val}{lastgcd} { m xor} lastxorv) 的最小的值即可。

    • 总时间复杂度为 (O(nlog n sqrt n))

    重点:( m gcd) 的取值次数最多有 (log) 次变化!

    代码

    #include<bits/stdc++.h>
    using namespace std;
    #define rep(i,a,b) for(int i=a;i<=b;++i)
    #define pb push_back
    typedef long long LL;
    inline int gi(){
    	int x=0,f=1;char ch=getchar();
    	while(!isdigit(ch))	{if(ch=='-') f=-1;ch=getchar();}
    	while(isdigit(ch)){x=(x<<3)+(x<<1)+ch-48;ch=getchar();}
    	return x*f;
    }
    template<typename T>inline bool Max(T &a,T b){return a<b?a=b,1:0;}
    template<typename T>inline bool Min(T &a,T b){return b<a?a=b,1:0;}
    typedef pair<LL,int> pii;
    const int N=1e5 + 7;
    int n,sz;
    int bl[N],a[N],G[N],X[N];
    char s[N];
    vector<pii>v[400];
    int gcd(int a,int b){
    	return !b?a:gcd(b,a%b);
    }
    void build(int z){
    	X[z]=0;v[z].clear();
    	rep(i, sz*(z-1)+1, min(sz*z,n)){
    		v[z].pb(make_pair(X[z]^=a[i],i));
    		G[z]=i==(sz*(z-1)+1)?a[i]:gcd(G[z],a[i]);
    	}
    	sort(v[z].begin(),v[z].end());
    }
    int query(LL val){
    	int lastg=a[1],lastx=0;
    	rep(i,1,sz){
    		lastg=i==1?a[1]:gcd(lastg,a[i]),lastx^=a[i];
    		if(1ll*lastg*lastx==val) return i;
    	}
    	rep(z,2,bl[n]){
    		if(gcd(lastg,G[z])==lastg){
    			LL to=(val/lastg)^lastx;lastx^=X[z];
    			if(val%lastg) continue;
    			int x=lower_bound(v[z].begin(),v[z].end(),make_pair(to,0))-v[z].begin();
    			if(x==v[z].size())  continue;
    			pii tmp=v[z][x];
    			if(tmp.first==to) return tmp.second;
    		}
    		else rep(i,sz*(z-1)+1,min(sz*z,n)){
    			lastg=gcd(lastg,a[i]),lastx^=a[i];
    			if(1ll*lastg*lastx==val) return i;
    		}
    	}
    	return 0;
    }
    int main(){
    	n=gi();sz=sqrt(n);
    	rep(i,1,n) a[i]=gi(),bl[i]=(i-1)/sz+1;
    	rep(z,1,bl[n]) build(z);
    	
    	int q=gi();
    	int x;LL y;
    	rep(i,1,q){
    		scanf("%s",s);
    		if(s[0]=='M') {
    			x=gi()+1,y=gi();
    			a[x]=y,build(bl[x]);
    		}else{
    			scanf("%lld",&y);
    			int res=query(y)-1;
    			if(res==-1) puts("no");
    			else printf("%d
    ",res);
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    常见数据结构使用场景
    Java与算法之(4)
    Java与算法之(3)
    Java与算法之(2)
    Java与算法之(1)
    Maven适配多种运行环境的打包方案
    从头开始基于Maven搭建SpringMVC+Mybatis项目(4)
    从头开始基于Maven搭建SpringMVC+Mybatis项目(3)
    从头开始基于Maven搭建SpringMVC+Mybatis项目(2)
    从头开始基于Maven搭建SpringMVC+Mybatis项目(1)
  • 原文地址:https://www.cnblogs.com/yqgAKIOI/p/9800196.html
Copyright © 2011-2022 走看看