链接https://pintia.cn/market/item/1442013218528759808
G
题意:求lim Σi=1~n ai*ln(1+bi * x)/x^t(x->0)
泰勒展开到x^5,然后找第一个系数不为0的x次幂,能找到提前输出,否则分子含有x^5的高阶无穷小,输出0
注意化简分式时候如果gcd函数x[i]放在了右边,要取绝对值,防止出现负数。
#include <iostream>
#include <cstring>
#include <algorithm>
#define int long long
using namespace std;
const int N = 1e5+10;
int x[10],n,t;
int gcd(int a,int b){
return !b?a:gcd(b,a%b);
}
signed main(){
cin>>n>>t;
for(int i=1,a,b;i<=n;i++){
cin>>a>>b;
x[1]+=a*b;
x[2]-=a*b*b;
x[3]+=a*b*b*b;
x[4]-=a*b*b*b*b;
x[5]+=a*b*b*b*b*b;
}
for(int i=1;i<=5;i++){
if(x[i]){
if(i<t){
cout<<"infinity";
return 0;
}
else if(i>t){
cout<<0;
return 0;
}
else {
if(i/abs(gcd(x[i],i))==1) cout<<x[i]/abs(gcd(x[i],i));
else cout<<x[i]/abs(gcd(x[i],i))<<"/"<<i/abs(gcd(x[i],i));
return 0;
}
}
}
cout<<0;
return 0;
}
L
题意:区间乘,区间每个数的欧拉函数和,原数和乘以的数均不超过100
筛出欧拉函数值以及每个数含有每个编号对应的质因子多少次幂
线段树维护区间欧拉函数和,以及区间共有的质因数,插入乘数的每个质因数及其次幂,
区间共有的质因子集合中有p时,Σphi[ip]=Σphi[i]p
否则 Σphi[ip]=Σphi[i](p-1),
若p的次幂不为1,则区间欧拉函数之和继续乘以p的y-1次幂即可
#include <iostream>
#include <cstring>
#include <algorithm>
#include <bitset>
#define int long long
using namespace std;
const int N = 1e5+10,M = 30,S = 211,mod=998244353;
bitset<M> bt[S];
int prime[N],st[N],cnt,phi[N],w[N];
int pw[S][M];
struct Node{
int l,r;
int v,mul;
bitset<M> p;
}tr[N*4];
int qmi(int a,int b){
int res=1%mod;
while(b){
if(b&1) res=res*a%mod;
a=a*a%mod;
b>>=1;
}
return res;
}
void init(int n){
phi[1]=1;
for(int i=2;i<=n;i++){
if(!st[i]){
prime[cnt++]=i;
phi[i]=i-1;
}
for(int j=0;i*prime[j]<=n;j++){
st[i*prime[j]]=1;
if(i%prime[j]==0){
phi[i*prime[j]]=phi[i]*prime[j];
break;
}
phi[i*prime[j]]=phi[i]*(prime[j]-1);
}
}
for(int i=2;i<=n;i++)
for(int j=0;j<cnt;j++)
if(i%prime[j]==0){
int t=i;
while(t%prime[j]==0){
pw[i][j]++;
t/=prime[j];
}
bt[i][j]=pw[i][j];
}
}
void pushup(Node &u,Node &l,Node &r){
u.v=(l.v+r.v)%mod;
u.p=l.p&r.p;
}
void pushup(int u){
pushup(tr[u],tr[u<<1],tr[u<<1|1]);
}
void pushdown(int u){
if(tr[u].mul!=1){
tr[u<<1].v=tr[u<<1].v*tr[u].mul%mod;
tr[u<<1|1].v=tr[u<<1|1].v*tr[u].mul%mod;
tr[u<<1].mul=tr[u<<1].mul*tr[u].mul%mod;
tr[u<<1|1].mul=tr[u<<1|1].mul*tr[u].mul%mod;
tr[u].mul=1;
}
}
void build(int u,int l,int r){
if(l==r){
tr[u]={l,r,phi[w[r]],1,bt[w[r]]};
return ;
}
tr[u]={l,r};
tr[u].mul=1;
int mid=l+r>>1;
build(u<<1,l,mid),build(u<<1|1,mid+1,r);
pushup(u);
}
void update(int u,int l,int r,int x,int y){
if(tr[u].l>=l&&tr[u].r<=r&&tr[u].p[x]){
tr[u].v=tr[u].v*qmi(prime[x],y)%mod;
tr[u].mul=tr[u].mul*qmi(prime[x],y)%mod;
return ;
}
if(tr[u].l==tr[u].r){
tr[u].v=tr[u].v*(prime[x]-1)%mod;
tr[u].v=tr[u].v*qmi(prime[x],y-1)%mod;
tr[u].p[x]=1;
return ;
}
pushdown(u);
int mid=tr[u].l+tr[u].r>>1;
if(l<=mid) update(u<<1,l,r,x,y);
if(mid<r) update(u<<1|1,l,r,x,y);
pushup(u);
}
Node query(int u,int l,int r){
if(tr[u].l>=l&&tr[u].r<=r) return tr[u];
pushdown(u);
int mid=tr[u].l+tr[u].r>>1;
if(r<=mid) return query(u<<1,l,r);
if(l>mid) return query(u<<1|1,l,r);
Node res,a=query(u<<1,l,r),b=query(u<<1|1,l,r);
pushup(res,a,b);
return res;
}
signed main(){
init(100);
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++) cin>>w[i];
build(1,1,n);
while(m--){
int op,l,r,x;
cin>>op>>l>>r;
if(!op){
cin>>x;
for(int i=0;i<cnt;i++)
if(x%prime[i]==0)
update(1,l,r,i,pw[x][i]);
}
else{
cout<<query(1,l,r).v<<endl;
}
}
return 0;
}