[六省联考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因为这个结果可能会很大,所以你只需要输出结果mod p的值即可。


Input

第一行有三个整数n,m,p,c,所有整数含义见问题描述。

接下来一行n个整数,表示a数组的初始值。

接下来m行,每行三个整数,其中第一个整数表示了操作的类型。

如果是0的话,表示这是一个修改操作,操作的参数为l,r。

如果是1的话,表示这是一个询问操作,操作的参数为l,r。

1 ≤ n ≤ 50000, 1 ≤ m ≤ 50000, 1 ≤ p ≤ 100000000, 0 < c <p, 0 ≤ ai < p


Output

对于每个询问操作,输出一行,包括一个整数表示答案mod p的值。


Sample Input

4 4 7 2

1 2 3 4

0 1 4

1 2 4

0 1 4

1 1 3


Sample Output

0

3

1 40 19910626 2
0
0 1 1
1 1 1
0 1 1
1 1 1
0 1 1
1 1 1
0 1 1
1 1 1
0 1 1
1 1 1
0 1 1
1 1 1
0 1 1
1 1 1
0 1 1
1 1 1
0 1 1
1 1 1
0 1 1
1 1 1
0 1 1
1 1 1
0 1 1
1 1 1
0 1 1
1 1 1
0 1 1
1 1 1
0 1 1
1 1 1
0 1 1
1 1 1
0 1 1
1 1 1
0 1 1
1 1 1
0 1 1
1 1 1
0 1 1
1 1 1 

in_put

1 

2 

4 

16 

65536 

11418102

18325590

13700558

13700558

13700558

13700558

13700558

13700558

13700558

13700558

13700558

13700558

13700558

13700558

13700558

out_put



考试时这个题感觉好神奇..当时某个学长将的时候一脸mengbier,整个人都noip了..什么事φ?

欧拉函数裸题,一个数c在mod一个数的时候,在最多log2p次会不变....

所以线段树维护区间和,区间修改最小值;

修改时遍历到每一个节点,暴力修改每一个改变的值,因为到一定的次数不会变,所以记录一个tag代表这个区间一共修改了多少次...

当l==r时就是那个点修改次数...最多log2p次就不用改了,时间复杂度n*2log(n)。记住,欧拉不要乱mod,会出事的...

#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<algorithm>
#define ll (long long)
#define LL long long
#define IN int
using namespace std;
const IN maxn=50000+99;
const IN N=10000+99;
int read(){
    int an=0,f=1;
    char ch=getchar();
    while(!(‘0‘<=ch&&ch<=‘9‘)){if(ch==‘-‘)f=-f;ch=getchar();}
    while(‘0‘<=ch&&ch<=‘9‘){an=an*10+ch-‘0‘;ch=getchar();}
    return an*f;
}
IN phi[35],a[maxn],F;
IN n,m,p,c;
IN prime[maxn],isp[maxn],k,maxp;//k是质数个数,ips说明这是和数
struct saber{
IN sum,tag,l,r;
}tr[maxn<<2];
IN Phi(IN x){
    LL ans=x;
    for(IN i=1;i<=k && prime[i]*prime[i]<=x;i++){
        if(!(x%prime[i]))ans=ans*(prime[i]-1)/prime[i];
        while(!(x%prime[i]))x=x/prime[i];
    }
    if(x>1)ans=ans/x*(x-1);
    return ans;
}
void euler(){
    for(IN i=2;i<=N;i++){
        if(!isp[i])k++,prime[k]=i;
        for(IN j=1;j<=k;j++){
            if(i*prime[j]>N)break;
            isp[i*prime[j]]=1;
            if(!(i%prime[j]))break;
        }
    }
    phi[maxp]=p;
    while(phi[maxp]!=1)maxp++,phi[maxp]=Phi(phi[maxp-1]);
    maxp++;
    phi[maxp]=1;
}
void build(IN k,IN l,IN r){
    tr[k].l=l;
    tr[k].r=r;
    if(l==r){
        tr[k].sum=a[l];
        return ;
    }
    IN mid=(l+r)>>1;
    build(k<<1,l,mid);
    build(k<<1|1,mid+1,r);
    tr[k].sum=tr[k<<1].sum+tr[k<<1|1].sum;
}
IN ask(IN k,IN i,IN j){
    IN l=tr[k].l,r=tr[k].r;
    if(l==i&&r==j)return tr[k].sum;
    IN mid=(l+r)>>1;
    if(mid>=j)return ask(k<<1,i,j);
    else if(i>mid)return ask(k<<1|1,i,j);
    else return (ask(k<<1,i,mid)+ask(k<<1|1,mid+1,j))%p;
}
IN qw(LL k,IN mod){
    LL ans=1;LL s=c;
    while(k){
        if(k&1)ans*=s;
        k>>=1;
        s*=s;
        if(s>=mod)F=1,s%=mod;
        if(ans>=mod)F=1,ans%=mod;
    }
    return ans%mod;
}
LL work(LL a,LL t){
    LL tmp=a;
    if(tmp>phi[t])tmp=tmp%phi[t]+phi[t];
    for(IN i=t;i>0;i--){
        F=0;tmp=qw(tmp,phi[i-1]);
        if(F)tmp+=phi[i-1],F=0;
    }
    return tmp;
}
void change(IN k,IN i,IN j){
    if(tr[k].tag>=maxp)return;
    LL l=tr[k].l,r=tr[k].r;
    if(l==r){
        tr[k].tag++;
        tr[k].sum=work(a[l],tr[k].tag)%p;
        return;
    }
    IN mid=(l+r)>>1;
    if(mid>=j)change(k<<1,i,j);
    else if(i>mid)change(k<<1|1,i,j);
    else {change(k<<1,i,mid);change(k<<1|1,mid+1,j);}
    tr[k].sum=tr[k<<1].sum+tr[k<<1|1].sum;
    tr[k].tag=min(tr[k<<1].tag,tr[k<<1|1].tag);
}
int main(){
    n=read();m=read();p=read();c=read();
    for(IN i=1;i<=n;i++)a[i]=read();
    euler();
    build(1,1,n);
    while(m)
    {m--;
        IN x,y,z;
        x=read();y=read();z=read();
        if(x){
            printf("%lld\n",ask(1,y,z)%p);
        }
        else {
            change(1,y,z);
        }
    }
    return 0;
}

相逢是问候

by:s_a_b_e_r


时间: 2024-10-11 09:14:59

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

[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)中的每

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

传送门 题解 扩展欧拉定理. 线段树维护,已经全改到底了的节点就不管,不然暴力修改下去. //Achen #include<algorithm> #include<iostream> #include<cstring> #include<cstdlib> #include<vector> #include<cstdio> #include<queue> #include<cmath> const int N=5

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)\)

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

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

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 向 它的代号 连

bzoj千题计划266:bzoj4872: [六省联考2017]分手是祝愿

http://www.lydsy.com/JudgeOnline/problem.php?id=4872 一种最优解是 从大到小灯有亮的就灭掉 最优解是唯一的,且关灯的顺序没有影响 最优解 对每个开关至多操作1次,(连带着的灯的亮灭改变不算) 设最优解 需要操作cnt次,那么就有cnt盏灯是正确的选择 设 f[i] 表示 有i种正确的选择  变为 有i-1种正确的选择 的 期望次数 那么在n盏灯中,有i盏灯操作1次 就可以 减少一次正确选择 有n-i盏灯是错误的选择,选了它还要把它还原,还原它也