P4140 奇数国

题目

P4140 奇数国

同时质数的值在这个题目当中只会取到前 (60) 个。

分析

因为题目给出的性质,很难不让人想到直接对于每一个数来维护每一个质因子的次数。

于是直接线段树维护即可,欧拉函数要算就直接使用计算式来做即可。

代码

#include<bits/stdc++.h>
using namespace std;
template <typename T>
inline void read(T &x){
    x=0;char ch=getchar();bool f=false;
    while(!isdigit(ch)){if(ch=='-'){f=true;}ch=getchar();}
    while(isdigit(ch)){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
    x=f?-x:x;
    return ;
}
template <typename T>
inline void write(T x){
    if(x<0) putchar('-'),x=-x;
    if(x>9) write(x/10);
    putchar(x%10^48);
    return ;
}
#define ll long long 
const int N=1e5+5,M=62,MOD=19961993;
int n;
int p[M]={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};
struct Node{
	int a[M];
	Node(){
		memset(a,0,sizeof(a));
	}
}t[N<<2];
Node operator +(Node x,Node y){for(int i=1;i<=60;i++) x.a[i]+=y.a[i];return x;}
void Pushup(int p){t[p]=t[p<<1]+t[p<<1|1];}
void Getnum(int u,int x){memset(t[u].a,0,sizeof(t[u].a));for(int i=1;i<=60;i++){if(x%p[i]) continue;while(x%p[i]==0) x/=p[i],t[u].a[i]++;}}
void Build(int p,int l,int r){
	if(l==r) return t[p].a[2]=1,void();
	int mid=(l+r)>>1;
	Build(p<<1,l,mid);Build(p<<1|1,mid+1,r);Pushup(p);
	return ;
}
void Modify(int p,int l,int r,int pos,int v){
	if(l==r) return Getnum(p,v),void();
	int mid=(l+r)>>1;
	if(pos<=mid) Modify(p<<1,l,mid,pos,v);
	else Modify(p<<1|1,mid+1,r,pos,v);
	Pushup(p);
	return ;
}
Node Query(int p,int l,int r,int ql,int qr){
	if(ql<=l&&qr>=r) return t[p];
	int mid=(l+r)>>1;Node res;
	if(qr<=mid) return Query(p<<1,l,mid,ql,qr);
	if(ql>mid) return Query(p<<1|1,mid+1,r,ql,qr);
	return Query(p<<1,l,mid,ql,qr)+Query(p<<1|1,mid+1,r,ql,qr); 
}
ll QuickPow(ll x,ll b){
	ll res=1;
	while(b){if(b&1) res=(res*x)%MOD;x=(x*x)%MOD;b>>=1;}
	return res;
}
ll calc(Node x){
	ll res=1;
	for(int i=1;i<=60;i++) if(x.a[i]) res=(res*(p[i]-1))%MOD,res=(res*QuickPow(p[i],x.a[i]-1))%MOD;
	return res;
}
int main(){
	read(n);
	Build(1,1,1e5);
	for(int i=1;i<=n;i++){
		int op,x,y;
		read(op),read(x),read(y);
		if(!op){
			Node tmp=Query(1,1,1e5,x,y);
			write(calc(tmp)),putchar('
');
		}
		else Modify(1,1,1e5,x,y); 
	} 
	return 0;
} 
原文地址:https://www.cnblogs.com/Akmaey/p/15174433.html