zoukankan      html  css  js  c++  java
  • THUSC2017杜老师

    如果当(R-L+1)很小时怎么做?
    完全平方数的质因数分解的每个质数的质数肯定是(0)
    考虑每个数的唯一分解,把它的每个质因数模(2)后视为一个向量。
    则判定是否合法,等于判定([L,R])中是否存在一个子集(S)使得(S)中的所有质因数分解向量在xor下(=0)
    答案就是(2^{自由基数量})
    考虑对每个数的所有质因数分块,一个数最多只会有一个(>sqrt{n})的质因子。
    所以这个数一定可以填上线性基的(>sqrt{n})的质因子的那一位。
    如果遇到第一个包含某个(>sqrt{n})质因数的数,则插入到这一位。
    否则把当前的数xor上对应的一位。
    由线性基的性质,这样子表示出的数不变
    这样子线性基的大小降低到(sqrt{n})
    考虑继续优化。
    当区间大小比较大时,线性基肯定容易被填满,所以当填满时即可跳出。
    这样子就能AC。
    当区间大小非常大时,线性基肯定会被填满,可以枚举每个素数计算。

    #include<bits/stdc++.h>
    using namespace std;
    #define N 10000010
    #define mo 998244353
    int qp(int x,int y){
    	int r=1;
    	for(;y;y>>=1,x=1ll*x*x%mo)
    		if(y&1)
    			r=1ll*r*x%mo;
    	return r;
    }
    int t,p[N],pr[N],ct,pp[N],tp,id[N],vi[N],po[10000],ok,vv[N],ii[N];
    bitset<510>bt[7010],bb[7010];
    void ins(bitset<510>bv){
    	for(int i=500;~i;i--)
    		if(bv[i]){
    			if(!bb[i][i]){
    				bb[i]=bv;
    				ok=0;
    				return;
    			}
    			bv^=bb[i];
    		}
    }
    signed main(){
    	for(int i=2;i<N;i++){
    		if(!vi[i]){
    			p[++ct]=i;
    			ii[i]=ct;
    			pr[i]=i;
    		}
    		for(int j=1;j<=ct&&p[j]*i<N;j++){
    			vi[p[j]*i]=1;
    			pr[i*p[j]]=p[j];
    			if(i%p[j]==0)
    				break;
    		}
    	}
    	memset(vi,0,sizeof(vi));
    	scanf("%d",&t);
    	while(t--){
    		int l,r,c=0;
    		scanf("%d%d",&l,&r);
    		if(r-l+1>=7000){
    			for(int i=1;p[i]<=r;i++)
    				if(r/p[i]!=(l-1)/p[i])
    					c++;
    			printf("%d
    ",qp(2,r-l+1-c));
    			continue;
    		}
    		for(int i=l;i<=r;i++){
    			int x=i;
    			while(x!=1){
    				if(ii[pr[x]]<=450&&!id[pr[x]]){
    					id[pr[x]]=++tp;
    					pp[tp]=pr[x];
    				}
    				if(ii[pr[x]]<=450)
    					bt[i-l].flip(id[pr[x]]);
    				x/=pr[x];
    			}
    		}
    		for(int i=l;i<=r;i++){
    			int x=i;
    			while(x!=1){
    				if(ii[pr[x]]>450&&!id[pr[x]]){
    					id[pr[x]]=++tp;
    					pp[tp]=pr[x];
    				}
    				if(ii[pr[x]]>450){
    					if(!vi[id[pr[x]]]){
    						vi[id[pr[x]]]=1;
    						po[id[pr[x]]]=i-l;
    						vv[i-l]=1;
    						c++;
    					}
    					else{
    						bt[i-l]^=bt[po[id[pr[x]]]];
    					}
    				}
    				x/=pr[x];
    			}
    		}
    		for(int i=0;i<r-l+1;i++)
    			if(!vv[i]){
    				ok=1;
    				ins(bt[i]);
    				if(!ok)
    					c++;
    			}
    		printf("%d
    ",qp(2,r-l+1-c));
    		for(int i=0;i<=7000;i++){
    			bb[i].reset();
    			bt[i].reset();
    		}
    		for(int i=0;i<=tp;i++){
    			id[pp[i]]=vi[i]=po[i]=0;
    			pp[i]=0;
    		}
    		for(int i=0;i<=r-l+1;i++)
    			vv[i]=0;
    		tp=0;
    	}
    }
    
  • 相关阅读:
    android git问题File not found: git.exe
    asp.net 连接数据库的问题总结
    asp.net记账本
    asp.net对数据库增删改操作
    asp.net 连接数据库操作
    第九、十周周记
    作业四-兴趣问题清单
    价值观作业
    第七周周记
    第三次作业问卷调查
  • 原文地址:https://www.cnblogs.com/ctmlpfs/p/14531934.html
Copyright © 2011-2022 走看看