[BZOJ4869][六省联考2017]相逢是问候(线段树+扩展欧拉定理)
4869: [Shoi2017]相逢是问候
Time Limit: 40 Sec Memory Limit: 512 MB
Submit: 1313 Solved: 471
[Submit][Status][Discuss]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 < pOutput
对于每个询问操作,输出一行,包括一个整数表示答案mod p的值。Sample Input
4 4 7 2
1 2 3 4
0 1 4
1 2 4
0 1 4
1 1 3Sample Output
0
3HINT
鸣谢多名网友提供正确数据,已重测!
Source
扩展欧拉定理:$a^x \equiv a^{x\% \phi (p)+[x> \phi (p)] \phi (p)} (mod p)$,a和p可以不互质。
我们可以不断展开:$c^{c^x} \equiv c^{c^x\% \phi (p)+\phi(p) } \equiv c^{c^{x\% \phi(\phi(p))+\phi(\phi(p))}\%\phi(p)+\phi(p)}(mod p)$,以此类推。
可以证明在$O(\log n)$次内模数会变为1,也就是最后会变成$x\%1+1$所以这个直接用线段树维护就好,如果一个区间内的所有数都变成1了就不必处理。
注意最后要加一个$\phi(1)$:https://blog.csdn.net/llgyc/article/details/71076172
#include<cstdio>
#include<algorithm>
#define ls (x<<1)
#define rs (x<<1)|1
#define lson ls,L,mid
#define rson rs,mid+1,R
#define rep(i,l,r) for (int i=l; i<=r; i++)
typedef long long ll;
using namespace std; const int N=100010;
int n,m,op,l,r,a[N],cnt,c,dep[N<<2];
ll sum[N<<2],mod[N]; ll phi(ll x){
ll res=x;
for (int i=2; i*i<=x; i++)
if (!(x%i)){
res=res*(i-1)/i;
while (!(x%i)) x/=i;
}
if (x>1) res=res*(x-1)/x;
return res;
} ll pow(ll a,ll b,ll p,bool &f){
ll res=1; f=0;
while (b){
if (b & 1) f|=(res*a>=p),res=(res*a)%p;
f|=(a*a>=p && b>1); a=(a*a)%p; b>>=1;
}
return res;
} ll calc(ll x,ll p){
ll res=x; bool f;
if (res>=mod[p]) res=res%mod[p]+mod[p];
while (p--){
res=pow(c,res,mod[p],f);
if (f) res+=mod[p];
}
return res%mod[0];
} void build(int x,int L,int R){
if (L==R) { dep[x]=0; sum[x]=a[L]; return; }
int mid=(L+R)>>1;
build(ls,L,mid); build(rs,mid+1,R);
sum[x]=(sum[ls]+sum[rs])%mod[0];
} void mdf(int x,int L,int R,int l,int r){
if (dep[x]>=cnt) return;
if (L==R){ sum[x]=calc(a[L],++dep[x]); return; }
int mid=(L+R)>>1;
if (r<=mid) mdf(lson,l,r);
else if (l>mid) mdf(rson,l,r);
else mdf(lson,l,mid),mdf(rson,mid+1,r);
dep[x]=min(dep[ls],dep[rs]); sum[x]=(sum[ls]+sum[rs])%mod[0];
} ll que(int x,int L,int R,int l,int r){
if (L==l && r==R) return sum[x];
int mid=(L+R)>>1;
if (r<=mid) return que(lson,l,r);
else if (l>mid) return que(rson,l,r);
else return (que(lson,l,mid)+que(rson,mid+1,r))%mod[0];
} int main(){
freopen("verbinden.in","r",stdin);
freopen("verbinden.out","w",stdout);
scanf("%d%d%lld%d",&n,&m,&mod[0],&c);
while (mod[cnt]!=1) cnt++,mod[cnt]=phi(mod[cnt-1]);
mod[++cnt]=1;
rep(i,1,n) scanf("%d",&a[i]);
build(1,1,n);
while (m--){
scanf("%d%d%d",&op,&l,&r);
if (!op) mdf(1,1,n,l,r); else printf("%lld\n",que(1,1,n,l,r));
}
return 0;
}
[BZOJ4869][六省联考2017]相逢是问候(线段树+扩展欧拉定理)的更多相关文章
- BZOJ4869 六省联考2017相逢是问候(线段树+欧拉函数)
由扩展欧拉定理,a^(a^(a^(……^x)))%p中x作为指数的模数应该是φ(φ(φ(φ(……p)))),而p取log次φ就会变为1,也即每个位置一旦被修改一定次数后就会变为定值.线段树维护区间剩余 ...
- bzoj千题计划271:bzoj4869: [六省联考2017]相逢是问候
http://www.lydsy.com/JudgeOnline/problem.php?id=4869 欧拉降幂+线段树,每个数最多降log次,模数就会降为1 #include<cmath&g ...
- 洛谷 P3747 [六省联考2017]相逢是问候 解题报告
P3747 [六省联考2017]相逢是问候 题目描述 \(\text {Informatik verbindet dich und mich.}\) 信息将你我连结. \(B\) 君希望以维护一个长度 ...
- 洛谷P3747 [六省联考2017]相逢是问候
传送门 题解 扩展欧拉定理. 线段树维护,已经全改到底了的节点就不管,不然暴力修改下去. //Achen #include<algorithm> #include<iostream& ...
- P3747 [六省联考2017]相逢是问候
题意 如果对一个数操作\(k\)次,那么这个数会变成\(c^{c^{...^{a_i}}}\),其中\(c\)有\(k\)个. 根据P4139 上帝与集合的正确用法这道题,我们可以知道一个数不断变为自 ...
- 【LuoguP3747】[六省联考2017] 相逢是问候
题目链接 题意 给定一个长度为 n 的序列 a , 给定一个正整数 c 每次修改操作是把一段区间内的数 \(x_i\) 修改为 \(c^{x_i}\) 询问区间和模 p 的结果 Sol 修改是把一个数 ...
- 【bzoj4869】[Shoi2017]相逢是问候 线段树+扩展欧拉定理
Description Informatikverbindetdichundmich. 信息将你我连结.B君希望以维护一个长度为n的数组,这个数组的下标为从1到n的正整数.一共有m个操作,可以 分为两 ...
- 2017 [六省联考] T2 相逢是问候
4869: [Shoi2017]相逢是问候 Time Limit: 40 Sec Memory Limit: 512 MBSubmit: 1205 Solved: 409[Submit][Stat ...
- 【BZOJ4873】[六省联考2017]寿司餐厅(网络流)
[BZOJ4873][六省联考2017]寿司餐厅(网络流) 题面 BZOJ 洛谷 题解 很有意思的题目 首先看到答案的计算方法,就很明显的感觉到是一个最大权闭合子图. 然后只需要考虑怎么构图就行了. ...
随机推荐
- 【BZOJ】4318: OSU! 期望DP
[题意]有一个长度为n的01序列,每一段极大的连续1的价值是L^3(长度L).现在给定n个实数表示该位为1的概率,求期望总价值.n<=10^5. [算法]期望DP [题解]后缀长度是一个很关键的 ...
- 可怕的npm蠕虫
https://hackernoon.com/im-harvesting-credit-card-numbers-and-passwords-from-your-site-here-s-how-9a8 ...
- C#里面中将字符串转为变量名
public partial class Form1 : Form { string str = "spp"; public string spp = "very goo ...
- Go语言 6 结构体、方法和接口
文章由作者马志国在博客园的原创,若转载请于明显处标记出处:http://www.cnblogs.com/mazg/ Go学习群:415660935 结构体(struct)是由一系列具有相同类型或不同类 ...
- 面向过程编程(OPP) 和面向对象编程(OOP)的关系
面向过程编程(OPP) 和面向对象编程(OOP)的关系 原文链接:http://blog.csdn.net/phphot/article/details/3985480 关于面向过程的编程(OPP)和 ...
- 28 - 生成器交互-__slots__-未实现异常
目录 1 生成器交互 2 slots 3 未实现和未实现异常 4 Python的对象模型 1 生成器交互 生成器提供了一个send方法用于动态的和生成器对象进行交互.怎么理解的呢?看下面的例子: de ...
- MySQL-索引工作原理及使用注意事项
1.为什么需要索引(Why is it needed)? 当数据保存在磁盘类存储介质上时,它是作为数据块存放.这些数据块是被当作一个整体来访问的,这样可以保证操作的原子性.硬盘数据块存储结构类似于链表 ...
- Machine Learning系列--隐马尔可夫模型的三大问题及求解方法
本文主要介绍隐马尔可夫模型以及该模型中的三大问题的解决方法. 隐马尔可夫模型的是处理序列问题的统计学模型,描述的过程为:由隐马尔科夫链随机生成不可观测的状态随机序列,然后各个状态分别生成一个观测,从而 ...
- reverse和reverse_copy函数的应用
reverse函数的作用是:反转一个容器内元素的顺序.函数参数:reverse(first,last);//first为容器的首迭代器,last为容器的末迭代器.它没有任何返回值. 这个函数比较简单, ...
- Codeforces 798D - Mike and distribution(二维贪心、(玄学)随机排列)
题目链接:http://codeforces.com/problemset/problem/798/D 题目大意:从长度为n的序列A和序列B中分别选出k个下表相同的数要求,设这两个序列中k个数和分别为 ...