• 洛谷P3747 [六省联考2017]相逢是问候


    传送门

    题解

    扩展欧拉定理。

    线段树维护,已经全改到底了的节点就不管,不然暴力修改下去。

    //Achen
    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<vector>
    #include<cstdio>
    #include<queue>
    #include<cmath>
    const int N=50000+7;
    #define For(i,a,b) for(int i=(a);i<=(b);i++)
    #define Rep(i,a,b) for(int i=(a);i>=(b);i--)
    typedef long long LL;
    using namespace std;
    LL n,m,p,pp,c,tp,cnt,phi[40],pr[40][N],pr2[40][N],mini[40];
    
    template<typename T>void read(T &x)  {
        char ch=getchar(); x=0; T f=1;
        while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
        if(ch=='-') f=-1,ch=getchar();
        for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
    }
    
    LL a[N],sg[N<<2],tot[N<<2];
    
    int get_phi(int x) {
        int up=sqrt(x),rs=x;
        For(i,2,up) {
            if(!(x%i)) {
                rs=rs-rs/i;
                while(!(x%i)) x/=i;
            }
        }
        if(x!=1) rs=rs-rs/x;
        return rs;
    }
    
    LL get(int i,int a) { //c^a%phi[i]
        return pr2[i][a/pp]*pr[i][a%pp]%phi[i];
    }
    
    #define lc x<<1
    #define rc x<<1|1
    #define mid ((l+r)>>1)
    void build(int x,int l,int r) {
        if(l==r) { sg[x]=a[l]; return; }
        build(lc,l,mid); build(rc,mid+1,r);
        sg[x]=(sg[lc]+sg[rc])%p;
        tot[x]=min(tot[lc],tot[rc]);
    }
    
    int lz[N<<1];
    void down(int x,int l_len,int r_len) {
        if(!lz[x]) return;
        if(l_len) { sg[lc]=l_len*c%p; tot[lc]=cnt; lz[lc]=1; }
        if(r_len) { sg[rc]=r_len*c%p; tot[rc]=cnt; lz[rc]=1; }
        lz[x]=0;
    }
    
    void update(int x,int l,int r,int ql,int qr) {
        if(tot[x]>=cnt) return;
        if(l>=ql&&r<=qr&&l==r) {
            tot[x]++; 
            sg[x]=a[l]>=phi[tot[x]+1]?a[l]%phi[tot[x]+1]+phi[tot[x]+1]:a[l];
            Rep(i,tot[x],1) {
                int now=sg[x]>=mini[i];
                sg[x]=get(i,sg[x]);
                if(now&&i!=1) sg[x]+=phi[i];
            }
            return ;
        }
        if(ql<=mid) update(lc,l,mid,ql,qr);
        if(qr>mid) update(rc,mid+1,r,ql,qr);
        sg[x]=(sg[lc]+sg[rc])%p;
        tot[x]=min(tot[lc],tot[rc]);
    }
    
    LL qry(int x,int l,int r,int ql,int qr) {
        if(l>=ql&&r<=qr) return sg[x];
        down(x,mid-l+1,r-mid);
        if(qr<=mid) return qry(lc,l,mid,ql,qr);
        if(ql>mid) return qry(rc,mid+1,r,ql,qr);
        return (qry(lc,l,mid,ql,qr)+qry(rc,mid+1,r,ql,qr))%p;
    }
    
    //#define DEBUG
    int main() {
    #ifdef DEBUG
        freopen("bzoj4869相逢是问候.in","r",stdin);
        freopen("bzoj4869相逢是问候.out","w",stdout);
    #endif
        read(n); read(m); read(p); read(c);
        For(i,1,n) read(a[i]);
        build(1,1,n);
        tp=p; phi[cnt=1]=tp;
        while(tp!=1) {
            phi[++cnt]=get_phi(tp);
            tp=phi[cnt];
        } phi[++cnt]=1; phi[cnt+1]=1;
        pp=1e4;
        For(i,1,cnt) {
            tp=1; int tc=0;
            if(c!=1) {
                for(;;) { 
                    tp*=c; tc++;
                    if(tp>=phi[i]) {
                        mini[i]=tc; 
                        break;
                    }
                } 
            } else mini[i]=1e8;
            pr[i][0]=pr2[i][0]=1;
            For(j,1,pp) 
                pr[i][j]=pr[i][j-1]*c%phi[i];
            For(j,1,pp) 
                pr2[i][j]=pr2[i][j-1]*pr[i][pp]%phi[i];
        } if(c!=1) { mini[cnt]=1; mini[cnt-1]=0; }
        while(m--) {
            int o,l,r;
            read(o); read(l); read(r);
            if(!o) update(1,1,n,l,r);
            else printf("%lld
    ",qry(1,1,n,l,r)%p);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    WinForm多线程+委托防止界面假死
    网页制作知识库
    HTML Agility Pack:簡單好用的快速 HTML Parser
    .NET 4.0 和 .NET 4.0 Client Profile 区别
    使用OPCNetAPI连接OPCServer
    Win7系统删除微软拼音
    Unity3D脚本18:可视化辅助设置类 Gizmos
    mysql 索引
    重启oracle方法一二三
    php7 安装扩展
  • 原文地址:https://www.cnblogs.com/Achenchen/p/8604365.html
Copyright © 2020-2023  润新知