• LOJ6231. GCD & XOR


    很好的题目。

    首先,(gcd) 有个很好的性质:

    对于一列数组,从左往右取前缀 (gcd),不同的值最多只有 (log w) 种。

    我的yy证明:

    对于 a[1],它最多为 (log w) 个质因子相乘(全取2),而每向后扫一个数,质因子数要么不变,要么减一,所以至多有 (log w) 个,所以有很多 (gcd) 是相同的。

    而且 (gcd) 是满足结合律的,所以很好预处理。

    所以我们可以倍增预处理 (gcd) ,然后开始扫,然后倍增跳,然后在找符合的 ( ext{xor}) 值。

    时间复杂度:(O(nlog^2 n))

    PS:map的小用法:map很适合这种查找的工作

    插入 m.insert(make_pair()) (O(log n))

    或直接用数组复制 m[key]=value... (O(log n))

    然后每次调用 m[key] 时,若不存在则会新建一个二元组 (key,zero),本题中就是这样使用的。(zero 是一个广义的零值)。

    然后删除 m.erase(it) 或 m.erase(make_pair()) (O(log n))

    迭代器:用法同 set

    empty,clear,size,begin,end同set (O(1))

    find(key):查找 key 值为 x 的二元组,若不存在则返回 m.end() (O(log n))

    然后对于 map 里的每一个元素 x,x->first 表示 key 值,x->second 表示 value。

    当然 map 里也是可以用 lower_bound(key) 返回的是 map 里的一个元素。

    #include<bits/stdc++.h>
    #define ll long long
    using namespace std;
    const int N=1e5+7;
    template <class I>
    inline void read(I &x){
        int f=1;
        char c;
        for(c=getchar();c<'0'||c>'9';c=getchar()) if(c=='-') f=-1;
        for(x=0;c>='0'&&c<='9';x=(x<<3)+(x<<1)+(c&15),c=getchar());
        x*=f;
    }
    int n;
    ll a[N],f[N][19],K,jc[19],xr[N];
    ll gcd(ll a,ll b){
    	return b?gcd(b,a%b):a;
    }
    map <ll,vector<int> > mp;
    map <ll,vector<int> >::iterator it;
    vector <int>::iterator vit;
    inline void init(){
    	jc[0]=1;
    	for(int i=1;i<19;i++) jc[i]=jc[i-1]<<1;
    	for(int i=1;i<=n;i++) f[i][0]=a[i];
    	for(int k=1;k<19;k++)
    		for(int i=1;i+jc[k]-1<=n;i++)
    			f[i][k]=gcd(f[i][k-1],f[i+jc[k-1]][k-1]);
    	for(int i=1;i<=n;i++) 
    		xr[i]=xr[i-1]^a[i],mp[xr[i]].push_back(i);
    }
    int main(){
    	//freopen("sequence.in","r",stdin);
    	//freopen("sequence.out","w",stdout);
    	read(n);
    	for(int i=1;i<=n;i++)
    		read(a[i]);
    	read(K);
    	init();
    	for(int l=1;l<=n;l++){
    		ll gd=a[l];
    		for(int i=l;i<=n;i++){
    			gd=gcd(a[i],gd);
    			int r=i;
    			for(int k=18;k>=0;k--){
    				if(r+jc[k]-1<=n&&(f[r][k]%gd==0)) r+=jc[k]-1;
    			}
    			if(K%gd) {
    				i=r;
    				continue;
    			}
    			it=mp.find((K/gd)^xr[l-1]);
    			if(it==mp.end()) {
    				i=r;
    				continue;}
    			vit=lower_bound((it->second).begin(),(it->second).end(),l);
    			if(vit==(it->second).end()||*vit>r){
    				i=r;
    				continue;
    			}
    			printf("%d %d
    ",l,*vit);
    			return 0;
    		}
    	}
    	puts("no solution");
    	return 0;
    }
    
    
  • 相关阅读:
    关于软件测试的浅谈
    软件测试中的压力测试和性能测试
    白盒测试一些方法
    浅谈黑盒测试
    关于判断是否为闰年以及异常处理问题
    软件测试用例
    等价类划分
    关于白盒测试
    【软件测试】软件测试方法划分
    【软件测试】灰盒测试
  • 原文地址:https://www.cnblogs.com/Hikigaya/p/11699473.html
Copyright © 2020-2023  润新知