[Shoi2017]相逢是问候
Posted yyys-
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[Shoi2017]相逢是问候相关的知识,希望对你有一定的参考价值。
这种“暴力线段树”可以考虑一下是不是有什么特殊性质。
对于这道题什么要知道:
可能这里写得比较清楚(摘自)
感觉就是一个迭代的过程。
而一个数在操作k次之后就可以不用再操作了。
然后使用欧拉定理的时候要特判一下:
x>=phi时,最后要加一个phi
小于则不加。
预处理出所有的phi,记得最后一个phi为1。
#include<bits/stdc++.h> #define LL long long #define N 50003 using namespace std; int read() { int x=0,f=1;char s=getchar(); while(s<‘0‘||s>‘9‘){if(s==‘-‘)f=-1;s=getchar();} while(s>=‘0‘&&s<=‘9‘){x=x*10+s-‘0‘;s=getchar();} return x*f; } LL n,m,p,c; LL num=0; LL a[N],P[N]; int ok=0; LL quick(LL a,LL x,LL mod) { LL ans=1; while(x) { if(x&1)ans=ans*a; a=a*a;x>>=1; if(ans>=mod)ok=1,ans%=mod; if(a>=mod)ok=1,a%=mod; } return ans; } int phi(int x) { int ans=x; for(int i=2;i*i<=x;++i) { if(x%i==0) { ans=ans/i*(i-1); while(x%i==0)x/=i; } } if(x!=1)ans=ans/x*(x-1); return ans; } LL sum[N<<2],ge[N<<2]; void pushup(int k) { sum[k]=(sum[k<<1]+sum[k<<1|1])%p; ge[k]=min(ge[k<<1],ge[k<<1|1]); } void build(int k,int l,int r) { if(l==r){sum[k]=a[l]%p;return;} int mid=(l+r)>>1; build(k<<1,l,mid); build(k<<1|1,mid+1,r); pushup(k); } LL query(int k,int L,int R,int l,int r) { LL ans=0; if(L>=l&&R<=r)return sum[k]; int mid=(L+R)>>1; if(l<=mid) { ans+=query(k<<1,L,mid,l,r); if(ans>=p)ans%=p; } if(r>mid) { ans+=query(k<<1|1,mid+1,R,l,r); if(ans>=p)ans%=p; } return ans%p; } LL cal(LL x,LL times) { if(x>P[times]) x=x%P[times]+P[times]; for(int i=times;i>=1;--i)//类似迭代求解 { ok=0;//特判一下 x=quick(c,x,P[i-1]); if(ok) x+=P[i-1]; } return x; } void modify(int k,int L,int R,int l,int r) { if(ge[k]>=num)return;//超过上限次数就不会再变了 if(L==R) { sum[k]=cal(a[L],++ge[k])%p; return ; } int mid=(L+R)>>1; if(l<=mid)modify(k<<1,L,mid,l,r); if(r>mid)modify(k<<1|1,mid+1,R,l,r); pushup(k); } int main() { // freopen("verbinden.in","r",stdin); // freopen("verbinden.out","w",stdout); n=read(),m=read(),p=read(),c=read(); int q=p; num=0; P[0]=q; while(q!=1)//预处理出phi { q=P[++num]=phi(q); } P[++num]=1; int flagg=0; for(int i=1;i<=n;++i)a[i]=read(); build(1,1,n); for(int i=1;i<=m;++i) { int op=read(),l=read(),r=read(); if(op==0) { modify(1,1,n,l,r);//a[i]=quick(c,a[i]); } else if(op==1) { LL ans=0; printf("%lld ",query(1,1,n,l,r)%p); } } }
以上是关于[Shoi2017]相逢是问候的主要内容,如果未能解决你的问题,请参考以下文章