题意:给定一个长度为 nnn 的序列 aia_iai​,维护 mmm 次操作:

  1. 区间执行 ai←caia_i \leftarrow c^{a_i}ai​←cai​;
  2. 区间求和 模 ppp。

其中 p,cp,cp,c 对所有操作相同。

n,m≤5×104,p≤108n,m\leq 5\times 10^4,p\leq 10^8n,m≤5×104,p≤108

不建议写,真的浪费生命

根据扩展欧拉定理,显然修改 O(log⁡p)O(\log p)O(logp) 次就没用了,所有数总共只会修改 O(nlog⁡P)O(n\log P)O(nlogP) 次。

但是暴力的话循环是占复杂度的,我们需要快速判断某个区间是否还需要修改。

似乎就只能线段树了?

暴力预处理出每个数 φ60\varphi \text{ } 60φ 60 次内的结果,然后线段树维护区间修改次数最小值和当前的区间和。修改的时候如果当前区间最小修改次数达到 606060 就退出,否则暴力递归。

复杂度 O(nlog⁡2P)O(n\log^2 P)O(nlog2P) ,会被卡,根号预处理快速幂可以 O(nlog⁡P)O(n\log P)O(nlogP) 。

听上去还挺美好,然而这题最恶心的地方在判断扩展欧拉定理的适用条件……

方法是在快速幂(或预处理幂)的时候记录是否取过模。

Q:如何证明不会出现 x>φ(p),cx%φ(p)+φ(p)<px>\varphi (p),c^{x \%\varphi(p)+\varphi(p)}<px>φ(p),cx%φ(p)+φ(p)<p ,然后继续迭代的时候崩掉的情况?

A:实际上 cφ(p)≥pc^{\varphi(p)} \geq pcφ(p)≥p 一般都是对的。

考虑计算 φ(p)\varphi(p)φ(p) 的一个很松的下界:φ(p)\varphi(p)φ(p) 考虑了每个质因子 xxx ,然后 p←p×x−1xp\leftarrow p\times \dfrac {x-1}xp←p×xx−1​

根据糖水原理,这个 xxx 越小效果会越明显。而 xxx 小的时候能得到的质因子也会更多。

而 10810^8108 以内的数最多只有 888 个质因子,所以可以估算一个下界 φ(p)p≥12×23×45×⋯×1819≈0.17\dfrac{\varphi(p)}{p}\geq\dfrac 12 \times \dfrac 23\times \dfrac 45\times \dots\times \dfrac {18}{19} \approx 0.17pφ(p)​≥21​×32​×54​×⋯×1918​≈0.17

相当于要证明: 2p/7≥p2^{p/7}\geq p2p/7≥p ,前者增长远快于后者,ppp 足够大(也就几十)的时候该式成立。

小数据暴力打表知只有个 p=6p=6p=6 ,但 666 只能取 222 次 φ\varphiφ ,所以也崩不了

证毕

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cctype>
#include <vector>
#include <bitset>
#include <utility>
#define MAXN 50005
#define re register
using namespace std;
typedef long long ll;
int n,q,c,flag;
inline int mul(const int& a,const int& b,const int& MOD)
{ll c=(ll)a*b;if (c>=MOD) flag=1;return c%MOD;
}
int m[60],len;
typedef pair<int,int> pi;
const int N=2e4;
pi p1[60][N+5],p2[60][N+5];//i,i*10000
inline void init()
{for (int T=0;T<=len;T++){p1[T][0]=p2[T][0]=make_pair(1,0);flag=0;for (int i=1;i<N;i++) p1[T][i].first=mul(p1[T][i-1].first,c,m[T]),p1[T][i].second=flag;p2[T][1].first=mul(p1[T][N-1].first,c,m[T]),p2[T][1].second=flag;for (int i=2;i<=N;i++) p2[T][i].first=mul(p2[T][i-1].first,p2[T][1].first,m[T]),p2[T][i].second=flag;}
}
inline int qpow(int p,int i)
{pi x=p1[i][p%N],y=p2[i][p/N];flag|=(x.second|y.second);return mul(x.first,y.first,m[i]);
}
inline int calcphi(int x)
{int ans=1;for (int i=2;i*i<=x;i++)if (x%i==0){ans*=i-1,x/=i;while (x%i==0) ans*=i,x/=i;}if (x>1) ans*=x-1;return ans;
}
int a[MAXN][60];
#define lc p<<1
#define rc p<<1|1
int sum[MAXN<<2],mcnt[MAXN<<2];
inline void update(int p){mcnt[p]=min(mcnt[lc],mcnt[rc]),sum[p]=(sum[lc]+sum[rc])%m[0];}
void build(int p,int l,int r)
{if (l==r){scanf("%d",&a[l][0]);for (int i=1;i<=len;i++){flag=0;int x=a[l][0];for (int j=i;j>=1;j--) x=qpow(x+m[j]*flag,j-1);a[l][i]=x;}sum[p]=a[l][0];return;}int mid=(l+r)>>1;build(lc,l,mid);build(rc,mid+1,r);update(p);
}
void modify(int p,int l,int r,int ql,int qr)
{if (qr<l||r<ql) return;if (mcnt[p]>=len) return;if (l==r) return (void)(sum[p]=a[l][++mcnt[p]]);int mid=(l+r)>>1;modify(lc,l,mid,ql,qr),modify(rc,mid+1,r,ql,qr);update(p);
}
int query(int p,int l,int r,int ql,int qr)
{if (qr<l||r<ql) return 0;if (ql<=l&&r<=qr) return sum[p];int mid=(l+r)>>1;return (query(lc,l,mid,ql,qr)+query(rc,mid+1,r,ql,qr))%m[0];
}
int main()
{scanf("%d%d%d%d",&n,&q,&m[0],&c);for (len=1;(m[len]=calcphi(m[len-1]))>1;++len);m[++len]=1;init();build(1,1,n);while (q--){int t,l,r;scanf("%d%d%d",&t,&l,&r);if (t==0) modify(1,1,n,l,r);else printf("%d\n",query(1,1,n,l,r));}return 0;
}

【SHOI2017】相逢是问候【扩展欧拉定理】【复杂度分析】【线段树】相关推荐

  1. [LNOI] 相逢是问候 || 扩展欧拉函数+线段树

    原题为2017六省联考的D1T3 给出一个序列,m次操作,模数p和参数c 操作分为两种: 1.将[l,r]区间内的每个数x变为\(c^x\) 2.求[l,r]区间内数的和%p 首先,我们要了解一些数论 ...

  2. bzoj4869: [Shoi2017]相逢是问候(欧拉函数+线段树)

    这题是六省联考的...据说数据还出了点锅,心疼六省选手QAQ 首先要知道扩展欧拉定理... 可以发现每次区间操作都会使模数进行一次phi操作,而一个数最多取logp次phi就会变成1,这时后面的指数就 ...

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

    好题啊! 调了一个中午,发现有一条语句 \(RE\) 了.在 \(windows\) 下没关系,\(linux\) 下有问题,大大的问题. while(phi[tot]!=1) phi[++tot]= ...

  4. [bzoj 4869] [六省联考2017] 相逢是问候

    相逢是问候 2017-09-09 Description Informatik verbindet dich und mich. 信息将你我连结.(s:看到这个就感觉有毒 B君希望以维护一个长度为n的 ...

  5. SHOI 2017 相逢是问候

    LOJ 2142 相逢是问候 这道题真的长见识 首先 这道题目很轻易地就能想到用 线段树 求和 但是题目的难点在于 caimodp≠caimodpmodpc^{a_i}\mod p \neq c^{a ...

  6. [HEOI2017] 相逢是问候

    Description 支持以下两个操作: 将第 \(l\) 个数到第 \(r\) 个数 \(a_l,a_{l+1},\dots a_r\) 中的每个数 \(a_i\) 替换为 \(c^{a_i}\) ...

  7. 【bzoj3884】上帝与集合的正确用法 扩展欧拉定理

    题目描述 根据一些书上的记载,上帝的一次失败的创世经历是这样的: 第一天, 上帝创造了一个世界的基本元素,称做"元". 第二天, 上帝创造了一个新的元素,称作"α&quo ...

  8. 欧拉定理(洛谷-P5091)(扩展欧拉定理实现)

    题目描述 给你三个正整数,a,m,b,你需要求:a^b mod m 输入输出格式 输入格式: 一行三个整数,a,m,b 对于全部数据: 1≤a≤10^9 1≤b≤10^{20000000} 1≤m≤1 ...

  9. Luogu P4139 上帝与集合的正确用法【扩展欧拉定理】By cellur925

    题目传送门 题目中的式子很符合扩展欧拉定理的样子.(如果你还不知扩展欧拉定理,戳).对于那一堆糟心的2,我们只需要递归即可,递归边界是模数为1. 另外,本题中好像必须要用快速乘的样子...否则无法通过 ...

最新文章

  1. mysql 排序取前4_MySQL时间段分组排序后取前10的问题?
  2. 今天新开通cnblogs,就说几句,留作纪念。
  3. linux 开机自启动设置 inittab 详解
  4. android中string.xml使用总结,string.xml 的作用以及意义——国际化应用
  5. 腾讯产品经理告诉你微信为什么没有用户等级?
  6. rhel 6下配置网络yum源(虚拟机环境下)
  7. python字符串去头尾_悉尼大学某蒟蒻的Python学习笔记
  8. 台式计算机听音乐,配置一台4000元的台式电脑,主要用于日常办公及上网查资料,听音乐,看电影及学习....
  9. 就业阶段-java语言进价_day06
  10. 【转载】MySQL学习总结一
  11. overridePendingTransition介绍
  12. iOS 关于UITableView的黑科技
  13. Html5添加audio音频播放器插件教程
  14. 通过servlet来实现对Mysql进行连接、插入、修改、删除操作
  15. 机器学习岗面试准备提纲笔记
  16. linux系统调用使用方法,Linux系统的使用以及系统调用的开发方法OS.ppt
  17. 小组学习电子教室等同屏工具调研
  18. 数学建模——相关系数(2)——假设检验
  19. 夏普红外测距模块使用笔记
  20. undefined reference to `timersub‘ 错误处理

热门文章

  1. 没有女朋友,可能是因为你数学不好
  2. 这些肢体语言竟然是这个意思! | 今日最佳
  3. 科幻作家阿西莫夫上世纪预言2019: 计算机彻底变革教育,太空移民进行中
  4. java对象头_我的并发编程(二):java对象头以及synchronized升级过程
  5. jpa 根据主键生成策略获取id_如何在使用JPA和Hibernate时选择id生成策略
  6. java jdbc 删除_java使用jdbc实现各种类型添加删除修改数据
  7. # 保持最外层获取焦点_大事件!沈阳爱尔白内障焕晶诊疗中心正式启用,两位PanOptix三焦点人工晶体植入患者清晰见证!...
  8. oracle类似isempty,NULLs和empty strings在不同数据库的中特点
  9. 满汉楼(德鲁伊连接池+DBUtils+DAO+Mysql)保姆级别分析+代码实现
  10. 10-5 5-5 查询只卖三种不同型号PC的厂商 (20 分)