• P4140 奇数国


    P4140

    先打质数表
    #include<cstdio>
    #include<cmath>
    using namespace std;
    bool shai(int n){
    	if(n < 2) return false;
    	int b = sqrt(n);
    	for(int i=2;i<=b;i++)
    	if(n % i == 0) return false;
    	return true;
    }
    int main(){
    	for(int i=1;i<=282;i++)
    	if(shai(i) == true)
    	printf("%d ",i);
    }
    2 3 5 7 11 13 17 19
     23 29 31 37 41 43 47 53
      59 61 67 71 73 79 83 89
       97 101 103 107 109 113 127
        131 137 139 149 151 157 163
    	 167 173 179 181 191 193 197
    	  199 211 223 227 229 233 239
    	   241 251 257 263 269 271 277 281
    

    一个地方总数不超100w 0区间乘,和区间查询
    1是单点修改 num编号 pro区间积 num整数+pro整数=1
    (转化为gcd(pro,num)=1)

    也就是说([1,N])里多少(num)(product)互质,即(φ(product))等于多少

    [φ(N)=n*prod_{质数p_i|n}(1-frac{1}{p_i})=prod_{p_i|n}p^k-p^{k-1}=n*prod_{p_i|n}frac{p_i-1}{p_i}\ 证明其实很简单~~唯一分解定理显然 ]

    看数据范围(mod~p),所以再线性推逆元

    	ny[1]=1;
    	for(int i=2;i<=281;i++)
    	ny[i]=(long long)(mod-mod/i)*ny[mod%i]%mod;
    

    区间维护:

    维护区间积 , 单点修改

    因为最多60个质数,把它们压在(long~~long)里 ,(or)相当于相乘操作

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    #define mod 19961993
    const int prime[61]={
    	0,2,3,5,7,11,13,17,19,
    	23,29,31,37,41,43,47,
    	53,59,61,67,71,73,79,
    	83,89,97,101,103,107,
    	109,113,127,131,137,
    	139,149,151,157,163,
    	167,173,179,181,191,
    	193,197,199,211,223,
    	227,229,233,239,241,
    	251,257,263,269,271,
    	277,281
    };
    int pni[300];
    	struct data{
    		long long sum;//区间(和)乘积 
    		long long p;//包含哪些素数。第i个二进制位如果是1,则有prime[i]这个素数,从1开始。 
    	}point[400010];
    	data ans;//记录查询答案。
    	void built(int l,int r,int o)
    	{
    		if(l==r) {point[o].sum=3;point[o].p=2;return ;}
    		int mid=(l+r)/2;
    		built(l,mid,o*2);
    		built(mid+1,r,o*2+1);		
    		point[o].sum=point[o*2].sum*point[o*2+1].sum%mod;
    		point[o].p=2;
    	}	
    	void chang(int l,int r,int o,const int t,const int k)//第t个点改为k 
    	{
    		if(l==r){
    			point[o].sum=k;
    			long long p=0;
    			for(int i=1;i<=60;i++){
    				if((k%prime[i])==0) p|=1LL<<(i-1);
    				point[o].p=p;
    			}
    			return ;
    		}
    		int mid=(l+r)/2;
    		if(t<=mid) chang(l,mid,o*2,t,k);
    		else chang(mid+1,r,o*2+1,t,k);
    		point[o].sum=point[o*2].sum*point[o*2+1].sum%mod;
    		point[o].p=point[o*2].p|point[o*2+1].p;
    	}
    	void quest(int l,int r,int o,int l1,int r1)//查询L到R。 
    	{
    		if(l1<=l&&r<=r1){
    			ans.sum=ans.sum*point[o].sum%mod;
    			ans.p|=point[o].p;
    			return ;
    		}
    		int mid=(l+r)/2;
    		if(l1<=mid) quest(l,mid,o*2,l1,r1);
    		if(mid<r1)  quest(mid+1,r,o*2+1,l1,r1);
    	} 
    int main()
    {
    	built(1,100000,1);
    	pni[1]=1;
    	for(int i=2;i<=281;i++)
    	pni[i]=(long long)(mod-mod/i)*pni[mod%i]%mod;
    	int tt;
    	scanf("%d",&tt);
    	while(tt--)
    	{
    		int x;scanf("%d",&x);
    	
    		if(x)
    		{
    		int t,k;
    		scanf("%d%d",&t,&k);
    		chang(1,100000,1,t,k);
    		}
    		else
    		{
    			int l1,r1;
    			ans.sum=1;
    			ans.p=0;
    			scanf("%d%d",&l1,&r1);
    			quest(1,100000,1,l1,r1);
    		
    			long long f=ans.sum;
    			for(int i=1;i<=60;i++)//计算φ 
    			if(ans.p&(1LL<<(i-1))) f=f*(prime[i]-1)%mod,f=f*pni[prime[i]]%mod;
    			printf("%d
    ",(int)f);
    		}
    	}
    	return 0;
    }
    
    
  • 相关阅读:
    2019-2020-1 20175317 《信息安全系统设计基础》第二周学习总结
    2019-2020-1 20175317 《信息安全系统设计基础》第一周学习总结
    2018-2019-2 20175317 实验五《网络编程与安全》实验报告
    20175317 《Java程序设计》个人项目
    回文数
    勾股数
    四方定理
    尼科彻斯定理
    实现mypwd
    2019-2020-1 20175301 20175305 20175318 实验五 通讯协议设计
  • 原文地址:https://www.cnblogs.com/shikeyu/p/13363223.html
Copyright © 2020-2023  润新知