洛谷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\n",qry(1,1,n,l,r)%p);
    }
    return 0;
}

原文地址:https://www.cnblogs.com/Achenchen/p/8604365.html

时间: 2024-10-04 03:44:08

洛谷P3747 [六省联考2017]相逢是问候的相关文章

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

题意 如果对一个数操作\(k\)次,那么这个数会变成\(c^{c^{...^{a_i}}}\),其中\(c\)有\(k\)个. 根据P4139 上帝与集合的正确用法这道题,我们可以知道一个数不断变为自己的欧拉函数,大约\(log\)次就会变成1,而任何数模\(1\)都是\(0\),于是我们可以用势能线段树解决. 因为模数不变,因此我们可以预处理所有\(\varphi(\varphi(...\varphi(p)...))\),之后在线段树上记录操作次数. 这样是三个\(log\)的,因为还要快速幂

[BZOJ4869][六省联考2017]相逢是问候(线段树+扩展欧拉定理)

4869: [Shoi2017]相逢是问候 Time Limit: 40 Sec  Memory Limit: 512 MBSubmit: 1313  Solved: 471[Submit][Status][Discuss] Description Informatikverbindetdichundmich. 信息将你我连结.B君希望以维护一个长度为n的数组,这个数组的下标为从1到n的正整数.一共有m个操作,可以 分为两种:0 l r表示将第l个到第r个数(al,al+1,...,ar)中的每

洛谷P3749 [六省联考2017]寿司餐厅

传送门 题解 这几道都是上周llj讲的题,题解也写得十分好了,所以直接贴了几个链接和代码. //Achen #include<algorithm> #include<iostream> #include<cstring> #include<cstdlib> #include<cstdio> #include<vector> #include<queue> #include<cmath> #include<

[六省联考2017]相逢是问候

相逢是问候 2017-09-09 Description Informatikverbindetdichundmich. 信息将你我连结.B君希望以维护一个长度为n的数组,这个数组的下标为从1到n的正整数.一共有m个操作,可以分为两种:0 l r表示将第l个到第r个数(al,al+1,...,ar)中的每一个数ai替换为c^ai,即c的ai次方,其中c是输入的一个常数,也就是执行赋值ai=c^ai1 l r求第l个到第r个数的和,也就是输出:sigma(ai),l<=i<=rai因为这个结果可

bzoj千题计划271:bzoj4869: [六省联考2017]相逢是问候

http://www.lydsy.com/JudgeOnline/problem.php?id=4869 欧拉降幂+线段树,每个数最多降log次,模数就会降为1 #include<cmath> #include<cstdio> #include<iostream> using namespace std; #define N 50001 int n,m,p,c; int a[N]; int sum[N<<2]; int tag[N<<2]; in

[六省联考2017]相逢是问候(线段树+拓展欧拉定理)

好题啊! 调了一个中午,发现有一条语句 \(RE\) 了.在 \(windows\) 下没关系,\(linux\) 下有问题,大大的问题. while(phi[tot]!=1) phi[++tot]=calc_phi(phi[tot-1]); 算是拓展欧拉定理的题吧.线段树只是一个工具,最主要还是暴力修改.因为 \(\varphi\) 不断套下去最多会有 \(\lfloor \log n\rfloor\) 层,所以我们对于每一层暴力算一遍,加上快速幂,时间复杂度 \(O(n\log^3 n)\)

P3746 [六省联考2017]组合数问题

P3746 [六省联考2017]组合数问题 \(dp_{i,j}\)表示前\(i\)个物品,取的物品模\(k\)等于\(r\),则\(dp_{i,j}=dp_{i-1,(j-1+k)%k}+dp_{i-1,j}\) \(dp_{i,0},dp_{i,1},dp_{i,2}.....dp_{i,k-1}\) \(\Longrightarrow\) \(dp_{i+1,0},dp_{i+1,1},dp_{i+1,2}.....dp_{i+1,k-1}\) 仔细想想,你能构造出矩阵的 #include

[luogu] P3745 [六省联考2017]期末考试 (贪心)

P3745 [六省联考2017]期末考试 题目描述 有 \(n\) 位同学,每位同学都参加了全部的 \(m\) 门课程的期末考试,都在焦急的等待成绩的公布. 第 \(i\) 位同学希望在第 \(t_i\)? 天或之前得知所有课程的成绩.如果在第 \(t_i\) 天,有至少一门课程的成绩没有公布,他就会等待最后公布成绩的课程公布成绩,每等待一天就会产生 \(C\) 不愉快度. 对于第 \(i\) 门课程,按照原本的计划,会在第 \(b_i\)? 天公布成绩. 有如下两种操作可以调整公布成绩的时间:

bzoj千题计划265:bzoj4873: [六省联考2017]寿司餐厅

http://www.lydsy.com/JudgeOnline/problem.php?id=4873 选a必选b,a依赖于b 最大权闭合子图模型 构图: 1.源点 向 正美味度区间 连 流量为 美味度 的边 2.负美味度区间 向 汇点 连 流量为 美味度的绝对值 的边 3.区间[i,j] 向 区间[i+1,j].区间[i,j-1] 连 流量为 inf 的边 4.区间[i,i] 向 寿司i 连 流量为 inf 的边 5.寿司i 向 汇点 连 流量为 寿司代号 的边 6.寿司i 向 它的代号 连