【bzoj4869】[Shoi2017]相逢是问候 线段树+扩展欧拉定理
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
Sol
根据扩展欧拉定理,参照bzoj3884,我们发现某个数字做一定次数比操作之后就不会变了,这个次数在\(logn\)左右,所以就可以用线段树维护区间和以及这个区间的数字有没有都处理完毕,然后直接维护即可。时间复杂度\(nlog^3n\),由于本题数据范围\(50000\),所以可以通过。
注意细节:判断某个数字有没有超过\(\varphi(p)\),以及\(\varphi(1)=\varphi(2)=1\),但是我们必须要在\(p=1\)的时候才能停止。
Code
#include <bits/stdc++.h>
using namespace std;
int n,m,P,c,K,op,l,r,a[50005],p[50005],V[50005],pr[50005],tot,sm[200005],mn[200005];
int phi(int x)
{
int res=x;
for(int i=1;pr[i]*pr[i]<=x;i++)
{
if(x%pr[i]) continue;
res-=res/pr[i];
while(x%pr[i]==0) x/=pr[i];
}
if(x>1) res-=res/x;return res;
}
void build(int x,int l,int r)
{
if(l==r){scanf("%d",&a[l]);sm[x]=a[l]%P;mn[x]=0;return;}
int M=(l+r)>>1;build(x<<1,l,M);build(x<<1|1,M+1,r);
sm[x]=(sm[x<<1]+sm[x<<1|1])%P;mn[x]=min(mn[x<<1],mn[x<<1|1]);
}
int ksm(int a,int b,int P,bool &f)
{
int res=1;bool gg=0;
for(;b;b>>=1,a=1ll*a*a%P)
{
if(b&1) f|=(gg|(1ll*res*a>=P)),res=1ll*res*a%P;
if(1ll*a*a>=P) gg=1;
}
return res;
}
int cal(int dep,int x)
{
int res=x;if(res>=p[dep]) res=res%p[dep]+p[dep];
while(dep)
{
dep--;bool flag=0;
res=ksm(c,res,p[dep],flag);
if(flag) res+=p[dep];
}
return res%p[dep];
}
void upd(int x,int l,int r,int b,int e)
{
if(mn[x]>=K) return;
if(l==r){mn[x]++;sm[x]=cal(mn[x],a[l]);return;}
int M=(l+r)>>1;
if(b<=M) upd(x*2,l,M,b,e);if(e>M) upd(x*2+1,M+1,r,b,e);
sm[x]=(sm[x<<1]+sm[x<<1|1])%P;mn[x]=min(mn[x<<1],mn[x<<1|1]);
}
int que(int x,int l,int r,int b,int e)
{
if(b<=l&&r<=e) return sm[x];
int M=(l+r)>>1;
return ((b<=M?que(x*2,l,M,b,e):0)+(e>M?que(x*2+1,M+1,r,b,e):0))%P;
}
int main()
{
for(int i=2;i<=50000;i++)
{
if(!V[i]) pr[++tot]=i;
for(int j=1;j<=tot&&i*pr[j]<=50000;j++){V[i*pr[j]]=1;if(i%pr[j]==0) break;}
}
scanf("%d%d%d%d",&n,&m,&P,&c);
p[0]=P;while(p[K]!=1){++K;p[K]=phi(p[K-1]);}p[++K]=1;
for(build(1,1,n);m--;)
{
scanf("%d%d%d",&op,&l,&r);
if(op==0) upd(1,1,n,l,r);
else printf("%d\n",que(1,1,n,l,r));
}
}
【bzoj4869】[Shoi2017]相逢是问候 线段树+扩展欧拉定理的更多相关文章
- [BZOJ4869][六省联考2017]相逢是问候(线段树+扩展欧拉定理)
4869: [Shoi2017]相逢是问候 Time Limit: 40 Sec Memory Limit: 512 MBSubmit: 1313 Solved: 471[Submit][Stat ...
- 【BZOJ4869】相逢是问候 [线段树][欧拉定理]
相逢是问候 Time Limit: 40 Sec Memory Limit: 512 MB[Submit][Status][Discuss] Description Informatikverbin ...
- BZOJ4869 [Shoi2017]相逢是问候 【扩展欧拉定理 + 线段树】
题目链接 BZOJ4869 题解 这题调得我怀疑人生,,结果就是因为某些地方\(sb\)地忘了取模 前置题目:BZOJ3884 扩展欧拉定理: \[c^a \equiv c^{a \mod \varp ...
- bzoj4869: [Shoi2017]相逢是问候(欧拉函数+线段树)
这题是六省联考的...据说数据还出了点锅,心疼六省选手QAQ 首先要知道扩展欧拉定理... 可以发现每次区间操作都会使模数进行一次phi操作,而一个数最多取logp次phi就会变成1,这时后面的指数就 ...
- Bzoj4869: [Shoi2017]相逢是问候
题面 传送门 Sol 摆定理 \[ a^b\equiv \begin{cases} a^{b\%\phi(p)}~~~~~~~~~~~gcd(a,p)=1\\ a^b~~~~~~~~~~~~~~~~~ ...
- bzoj 4869: [Shoi2017]相逢是问候 [扩展欧拉定理 线段树]
4869: [Shoi2017]相逢是问候 题意:一个序列,支持区间\(a_i \leftarrow c^{a_i}\),区间求和.在模p意义下. 类似于开根操作,每次取phi在log次后就不变了. ...
- 【BZOJ4869】相逢是问候(线段树,欧拉定理)
[BZOJ4869]相逢是问候(线段树,欧拉定理) 题面 BZOJ 题解 根据欧拉定理递归计算(类似上帝与集合的正确用法) 所以我们可以用线段树维护区间最少的被更新的多少次 如果超过了\(\varph ...
- BZOJ:4869: [Shoi2017]相逢是问候
4869: [Shoi2017]相逢是问候 先说点正经的…… 显然做了有限次(我只知道是有限次,而且不会大,别人说是log次?)修改以后会达到不动点,即以后怎么修改都不变了. 然后就随便做了.(3个l ...
- 【bzoj4869】[Shoi2017]相逢是问候 扩展欧拉定理+并查集+树状数组
题目描述 Informatik verbindet dich und mich. 信息将你我连结. B君希望以维护一个长度为n的数组,这个数组的下标为从1到n的正整数.一共有m个操作,可以分为两种:0 ...
随机推荐
- Python之购物商场
作业:购物商场 1.流程图 2.初始化用户账号存储文件 初始化存储一个空的用户账号字典,保存到文件 user.pkl.执行如下代码,即可初始化完成. #!/usr/bin/env python # - ...
- FB联网无人机取得重大进展 实现首次成功着陆
科技讯6月30日消息,据Engadget报道,在过去的几年里,世界最大社交网络Facebook始终在测试其太阳能无人飞机Aquila.2016年6月份,这种联网无人机在美国亚利桑那州的尤马进行了首次全 ...
- 一只小蜜蜂(斐波那契dp)
有一只经过训练的蜜蜂只能爬向右侧相邻的蜂房,不能反向爬行.请编程计算蜜蜂从蜂房a爬到蜂房b的可能路线数. 其中,蜂房的结构如下所示. Input输入数据的第一行是一个整数N,表示测试实例的个数,然后是 ...
- ssh免密连接远程服务器
ssh免密连接远程服务器 借助ssky-keygen和ssh-copy-id工具,通过4个简单的步骤实现无需输入密码登录远程Linux主机 1 生成密钥 通过内置的工具生成RSA算法加密的密钥 ssh ...
- 模拟linux的内存分配与回收
模拟linux的内存分配与回收 要求 通过深入理解内存分配管理的三种算法,定义相应的数据结构,编写具体代码. 充分模拟三种算法的实现过程,并通过对比,分析三种算法的优劣. (1)掌握内存分配FF,BF ...
- java5 CyclicBarrier同步工具
CyclicBarrier是一个同步辅助类,它允许一组线程互相等待,直到到达某个公共屏障点(common barrier point).在涉及一组固定大小的线程的程序中,这些线程必须不时地互相等待,此 ...
- saltstack系列(三)——zmq订阅/发布模式
zmq订阅发布模式 server端代码: #coding=utf-8 ''''' 服务端,发布模式 ''' import zmq from random import randrange contex ...
- Spring总结三:DI(依赖注入)
简介: 所谓的依赖注入,其实是当一个bean实例引用到了另外一个bean实例时spring容器帮助我们创建依赖bean实例并注入(传递)到另一个bean中,比如你使用Spring容器创建的对象A里面需 ...
- 【bzoj1016】[JSOI2008]最小生成树计数
1016: [JSOI2008]最小生成树计数 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 4863 Solved: 1973[Submit][St ...
- 解决0RA-04031故障
1.客户反应报表数据很慢,简单查询5分钟都出不来. 2.登陆数据库服务器检查日志:Thu Mar 21 16:20:30 2013Errors in file /opt/oracle/diag/rdb ...