虽说是一道裸题,但还是让小C学到了一点姿势的。

Description

  给定一个长度为n的数组w,模数m和询问次数q,每次询问给定l,r,求:

    

  对m取模的值。

Input

  第一行两个整数n,m,表示数组长度和模数。
  接下来一行n个数,表示w数组。
  接下来一行一个整数q,表示询问次数。
  接下来q行,每行两个整数l,r,表示一次询问。

Output

  对于每次询问,输出一行一个整数表示答案。

Sample Input

  6 1000000000
  1 2 2 3 3 3
  8
  1 1
  1 6
  2 2
  2 3
  2 4
  4 4
  4 5
  4 6

Sample Output

  1
  1
  2
  4
  256
  3
  27
  597484987

HINT

  1 ≤ n ≤ 105,1 ≤ m ≤ 109,1 ≤ wi ≤ 109,1 ≤ q ≤ 105,1 ≤ l ≤ r ≤ n

Solution

  看到这么清奇的式子,你大概会第一时间想到降幂大法吧?

  先说说扩展欧拉定理,对于任意正整数a,b,p:

    

  所以假设堆叠的幂次足够大,那么式子就可以转化为:

      

  

  已知p经过至多2log次phi就会变成1。

  所以递归求解,至多走到2log层模数就会变成1,所以返回0就行。

  所以这道题就非常显然了,首先预处理出m的所有phi,对于每个询问,从l开始直接递归暴力,直到模数为1时返回。

  还有一个问题,在求a^b%p的时候,怎么比较b和phi(p)的大小呢?

  一种思路就是暴力计算a的后log项的值,注意还要特判1的情况,但这样写起来确实麻烦。

  当然,有一种非常精妙的取模写法:

int modulo(ll x,int mod) {return x<mod?x:x%mod+mod;}

  这是在做什么呢?这就是在比较b和phi(p)的大小,如果b<phi(p),返回b;否则返回b%phi(p)+phi(p)。

  然后原式就变成了这样:

    

  这样做看上去漏洞百出,可能的情况是,原本我们要计算,其中大等于

  然而我们计算,将取模后,却发现小于了。

  是否有这种可能呢?

  其实就相当于判断是否有可能成立,我们可以发现,当a>2时式子是不可能成立的。

  所以我们来看一看 是否有可能成立。

  有可能。

  当且仅当p=6时,不等式成立。

  然而6有什么特殊的性质呢?

  我们发现phi(x)=6只有三个解:x=7,x=9或x=18。

  所以接下来我们只要证明   和   即  和  在对x取模的意义下相等即可。(其中phi(x)=6)

  若a为x的倍数,显然它们对x取模都等于0,对于答案无影响。

  当x=7时,,所以 

  当x=9时,若 ,则影响同上;

        若 ,一定有,所以一定有 

               所以一定有 ,对于答案是没有影响的;

  当x=18时,若  或 ,则影响同上;

       我们有一个显然的结论:同余方程  的解为 

       若 ,则 ,则 ,则 

       若 ,则  且 ,则 ,则 

  所以综上,我们就证明了该算法的正确性。

  时间复杂度

#include <cstdio>
#include <cstring>
#include <algorithm>
#define ll long long
#define MN 100005
using namespace std;
int a[MN],mod[MN];
int n,p;
bool fg; inline int read()
{
int n=,f=; char c=getchar();
while (c<'' || c>'') {if(c=='-')f=-; c=getchar();}
while (c>='' && c<='') {n=n*+c-''; c=getchar();}
return n*f;
} inline int pro(ll x,int md) {return x<md?x:x%md+md;}
inline int mi(int x,int y,int md)
{
register int z=;
for (;y;x=pro(1LL*x*x,md),y>>=)
if (y&) z=pro(1LL*z*x,md);
return z;
} int dfs(int x,int y,int lim)
{
if (x==lim) return a[x]>=mod[y]?a[x]%mod[y]+mod[y]:a[x];
if (mod[y]==) return ;
return mi(a[x],dfs(x+,y+,lim),mod[y]);
} int main()
{
register int i,j,x,y;
n=read(); mod[]=read();
for (i=;mod[i]>;++i)
{
mod[i+]=x=mod[i];
for (j=;j*j<=x;++j)
{
for (fg=;x%j==;x/=j,fg=true);
if (fg) mod[i+]=1LL*mod[i+]*(j-)/j;
}
if (x>) mod[i+]=1LL*mod[i+]*(x-)/x;
}
for (i=;i<=n;++i) a[i]=read();
for (p=read();p;--p)
{
x=read(); y=read();
printf("%d\n",dfs(x,,y)%mod[]);
}
}

Last Word

  打Codeforces的时候正纳闷这种情况该怎么处理,却发现大佬们清一色都是这么写的。

  小C觉得自己的证明蠢得不行啊……

  如果读者有更直观的证明该算法的正确性的方法请务必告诉小C。

[Codeforces]906D Power Tower的更多相关文章

  1. CodeForces - 906D Power Tower(欧拉降幂定理)

    Power Tower CodeForces - 906D 题目大意:有N个数字,然后给你q个区间,要你求每一个区间中所有的数字从左到右依次垒起来的次方的幂对m取模之后的数字是多少. 用到一个新知识, ...

  2. Codeforces 906D Power Tower(欧拉函数 + 欧拉公式)

    题目链接  Power Tower 题意  给定一个序列,每次给定$l, r$ 求$w_{l}^{w_{l+1}^{w_{l+2}^{...^{w_{r}}}}}$  对m取模的值 根据这个公式 每次 ...

  3. Codeforces Round #454 (Div. 1) CodeForces 906D Power Tower (欧拉降幂)

    题目链接:http://codeforces.com/contest/906/problem/D 题目大意:给定n个整数w[1],w[2],……,w[n],和一个数m,然后有q个询问,每个询问给出一个 ...

  4. [CodeForces - 906D] Power Tower——扩展欧拉定理

    题意 给你 $n$ 个 $w_i$ 和一个数 $p$,$q$个询问,每次询问一个区间 $[l,r] $,求 $w_l ^{w_{l+1}^{{\vdots}^{w_r}}} \ \% p$ 分析 由扩 ...

  5. CodeForces 907F Power Tower(扩展欧拉定理)

    Priests of the Quetzalcoatl cult want to build a tower to represent a power of their god. Tower is u ...

  6. 【CodeForces】906 D. Power Tower 扩展欧拉定理

    [题目]D. Power Tower [题意]给定长度为n的正整数序列和模数m,q次询问区间[l,r]累乘幂%m的答案.n,q<=10^5,m,ai<=10^9. [算法]扩展欧拉定理 [ ...

  7. Codeforces Round #454 D. Power Tower (广义欧拉降幂)

    D. Power Tower time limit per test 4.5 seconds memory limit per test 256 megabytes input standard in ...

  8. CodeForces 906D (欧拉降幂)

    Power Tower •题意 求$w_{l}^{w_{l+1}^{w_{l+2}^{w_{l+3}^{w_{l+4}^{w_{l+5}^{...^{w_{r}}}}}}}}$ 对m取模的值 •思路 ...

  9. [CodeForces - 1225D]Power Products 【数论】 【分解质因数】

    [CodeForces - 1225D]Power Products [数论] [分解质因数] 标签:题解 codeforces题解 数论 题目描述 Time limit 2000 ms Memory ...

随机推荐

  1. 【iOS】跳转到设置页面

    iOS8.0以后有效 定位服务 定位服务有很多APP都有,如果用户关闭了定位,那么,我们在APP里面可以提示用户打开定位服务.点击到设置界面设置,直接跳到定位服务设置界面.代码如下: 1 2 3 4 ...

  2. 老板怎么办,我们网站遭到DDoS攻击又挂了?

    相信现在正在阅读此文的你,一定听说过发生在上个月的史上最大的DDoS攻击. 美国东部时间2月28日,GitHub在一瞬间遭到高达1.35Tbps的带宽攻击.这次DDoS攻击几乎可以堪称是互联网有史以来 ...

  3. Python 迭代器之列表解析与生成器

     [TOC] 1. 列表解析 1.1 列表解析基础 列表解析把任意一个表达式应用到一个迭代对象中的元素 Python内置ord函数会返回一个字符的ASCII整数编码(chr函数是它的逆过程, 它将A ...

  4. H5新特性之webWorker

    众所周知javascript是单线程语言,这就是js开发难度较低的原因了,因为不需要解决多线程的资源共享问题(例如死锁),但是单线程性能并不好,因此多了一个webWorker实现js的多进程来提升js ...

  5. 谈谈ASP.NET Core中的ResponseCaching

    前言 前面的博客谈的大多数都是针对数据的缓存,今天我们来换换口味.来谈谈在ASP.NET Core中的ResponseCaching,与ResponseCaching关联密切的也就是常说的HTTP缓存 ...

  6. vue组件详解(三)——组件通信

    组件之间通信可以用下图表示: 组件关系可分为父子组件通信.兄弟组件通信.跨级组件通信. 一.自定义事件 当子组件需要向父组件传递数据时,就要用到自定义事件. 子组件用$emit ()来触发事件,父组件 ...

  7. Apollo单向SSL认证(1)

    参考链接:https://www.cnblogs.com/benwu/articles/4891758.html keytool -genkey -alias mybroker -keyalg RSA ...

  8. Docker学习笔记 - Docker的数据卷容器

    一.什么是数据卷容器 如果你有一些持续更新的数据需要在容器之间共享,最好创建数据卷容器. 数据卷容器:用于容器间的数据共享,主动挂载宿主机目录,用于其他容器挂载和共享. 二.数据卷容器的操作 1.创建 ...

  9. django的models模型类的常用数据类型和选项

    django框架的models模块ORM框架,能够让我们通过编写类的方式,帮助我们自动生成数据库表. 生成的数据库表名为 应用模块名称_类名 数据库表中字段名 如果我们没有在参数中指定,就是我们写的类 ...

  10. leetcode算法: Keyboard Row

    Given a List of words, return the words that can be typed using letters of alphabet on only one row' ...