[Shoi2017] Encounter is greeting

Portal

This "Violence segment tree" can think about is not what special properties.

This question is for what to know:

 

 

 Here may be written more clearly ( Excerpt )

Feeling process is an iterative process.

And a number of times after the operation k can no longer operate.

Euler's theorem then use the time to look at special sentence:

x> time = phi, and finally to add a phi

Not less than plus.

 

 All of the pre-phi, phi remember the last one.

#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 & lt, int L, int R & lt) 
{ 
    if (GE [K]> = NUM) return ; // exceeded the maximum number will not changed 
    if (L == R & lt) 
    { 
        SUM [K] = CAL (A [L], GE ++ [K])% P;
         return ; 
    } 
    int MID = (L + R & lt) >> . 1 ;
     IF (L <= MID ) Modify (K << . 1 , L, MID, L, R & lt);
     IF (R & lt> 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\n",query(1,1,n,l,r)%p);
        }
    }
} 
View Code

Guess you like

Origin www.cnblogs.com/yyys-/p/11544402.html