[LNOI] 相逢是问候 || 扩展欧拉函数+线段树
原题为2017六省联考的D1T3
给出一个序列,m次操作,模数p和参数c
操作分为两种:
1、将[l,r]区间内的每个数x变为\(c^x\)
2、求[l,r]区间内数的和%p
首先,我们要了解一些数论姿势:
1、扩展欧拉定理
//我们熟知的费马小定理用于p是质数,欧拉定理用于a,p互质,而这道题都不满足这个限制
当\((b>=\phi(p))\)时,\(a^b=a^{b\mod \phi(p) + \phi(p)}\)
2、(其实不算数论姿势)一个数最多经过log此\(\phi\)就会变成1
所以我们发现,一个数在经过几次变化后,指数永远是\(x\mod1+1\),也就是1,它就再也不变了!
//上面这里不理解的话,可以考虑这样一道题
//给定一个长度为n的序列a,每次询问区间[l,r] \(a_l^{a_{l+1}^{…}}\)的值。\(n<=10^5,m<=10^9\)
//原题应该是叫power tower
所以我们建一棵线段树,维护当前区间和和这个区间中被修改的最小次数。
预处理出对于mod p来讲,几次后一定会不变,记为k。每次修改将当前位置的修改次数++。如果这个区间的最小修改次数>=k,那么就不需要修改了,否则暴力修改。
因为每次的修改次数不一样,所以要用初值a[i]计算times后当前数会变为什么。
因为有n个数,每个数会被暴力修改\(\log(p)\)次,每次修改是\(\log(n)\)的,再乘上快速幂的复杂度\(\log\)就是\(O(nlog^3)\)
这样基本能过了,但是被卡常的话就不稳了。可以考虑预处理c的快速幂,反正c是固定的……
//bzoj不预处理就能过,洛谷过不了(也可能是博主写的比较菜)
贴一份没有预处理的代码
#include<cstdio>
#include<algorithm>
#define N 50010
#define M 10010
typedef long long ll;
using namespace std;
int a[N],n,m,prime[N],tot,p[N],P,c,op,l,r,k,MOD;
bool np[N];
struct hhh
{
int l,r,sum,is;
}tre[4*N];
int read()
{
int ans=0,fu=1;
char j=getchar();
for (;j<'0' || j>'9';j=getchar()) if (j=='-') fu=-1;
for (;j>='0' && j<='9';j=getchar()) ans*=10,ans+=j-'0';
return ans*fu;
}
int ksm(int x,int y,int mo,bool &flag)
{
int ret=1;
bool big=0;
while (y)
{
if (y&1)
{
flag|=big|((ll)ret*x>=mo);
ret=(ll)ret*x%mo;
}
if ((ll)x*x>=mo) big=1;
x=(ll)x*x%mo;
y>>=1;
}
return ret;
}
void build(int i,int l,int r)
{
tre[i].l=l;tre[i].r=r;tre[i].is=0;
if (l==r)
{
tre[i].sum=a[l]%P;
return ;
}
int mid=(l+r)>>1;
build(i*2,l,mid);
build(i*2+1,mid+1,r);
tre[i].sum=(tre[i*2].sum+tre[i*2+1].sum)%P;
}
int calc(int x,int dep)
{
int ret=x;
if (ret>=p[dep]) ret=ret%p[dep]+p[dep];
while (dep)
{
dep--;
bool flag=0;
ret=ksm(c,ret,p[dep],flag);
if (flag) ret+=p[dep];
}
return ret%P;
}
void modify(int i,int l,int r)
{
if (l>tre[i].r || r<tre[i].l) return ;
if (tre[i].is>=k) return ;
if (tre[i].l==tre[i].r)
{
tre[i].is++;
tre[i].sum=calc(a[tre[i].l],tre[i].is);
return ;
}
modify(i*2,l,r);
modify(i*2+1,l,r);
tre[i].sum=(tre[i*2].sum+tre[i*2+1].sum)%P;
tre[i].is=min(tre[i*2].is,tre[i*2+1].is);
}
int query(int i,int l,int r)
{
if (l>tre[i].r || r<tre[i].l) return 0;
if (tre[i].l>=l && tre[i].r<=r) return tre[i].sum;
return (query(i*2,l,r)+query(i*2+1,l,r))%P;
}
int phi(int n)
{
int res=n,a=n;
for(int i=2; i*i<=a; i++)
if(a%i==0)
{
res=res/i*(i-1);
while (a%i==0) a/=i;
}
if (a>1) res=res/a*(a-1);
return res;
}
int main()
{
n=read();m=read();P=read();c=read();
for (int i=1;i<=n;i++) a[i]=read();
p[0]=P;
while (p[k]!=1) { ++k; p[k]=phi(p[k-1]); }
p[++k]=1;
build(1,1,n);
while (m--)
{
op=read();l=read();r=read();
if (op) printf("%d\n",query(1,l,r));
else modify(1,l,r);
}
return 0;
}
[LNOI] 相逢是问候 || 扩展欧拉函数+线段树的更多相关文章
- LOJ #2142. 「SHOI2017」相逢是问候(欧拉函数 + 线段树)
题意 给出一个长度为 \(n\) 的序列 \(\{a_i\}\) 以及一个数 \(p\) ,现在有 \(m\) 次操作,每次操作将 \([l, r]\) 区间内的 \(a_i\) 变成 \(c^{a_ ...
- bzoj4869: [Shoi2017]相逢是问候(欧拉函数+线段树)
这题是六省联考的...据说数据还出了点锅,心疼六省选手QAQ 首先要知道扩展欧拉定理... 可以发现每次区间操作都会使模数进行一次phi操作,而一个数最多取logp次phi就会变成1,这时后面的指数就 ...
- LightOJ 1370 Bi-shoe and Phi-shoe 欧拉函数+线段树
分析:对于每个数,找到欧拉函数值大于它的,且标号最小的,预处理欧拉函数,然后按值建线段树就可以了 #include <iostream> #include <stdio.h> ...
- loj1370(欧拉函数+线段树)
传送门:Bi-shoe and Phi-shoe 题意:给出多个n(1<=n<=1e6),求满足phi(x)>=n的最小的x之和. 分析:先预处理出1~1e6的欧拉函数,然后建立一颗 ...
- [BZOJ4026]dC Loves Number Theory 欧拉函数+线段树
链接 题意:给定长度为 \(n\) 的序列 A,每次求区间 \([l,r]\) 的乘积的欧拉函数 题解 考虑离线怎么搞,将询问按右端点排序,然后按顺序扫这个序列 对于每个 \(A_i\) ,枚举它的质 ...
- 【bzoj4869】[Shoi2017]相逢是问候 扩展欧拉定理+并查集+树状数组
题目描述 Informatik verbindet dich und mich. 信息将你我连结. B君希望以维护一个长度为n的数组,这个数组的下标为从1到n的正整数.一共有m个操作,可以分为两种:0 ...
- BZOJ 4034: [HAOI2015]树上操作 [欧拉序列 线段树]
题意: 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x 为根的子树中所有点的点权都增加 a . 操作 3 :询问某个节点 x 到根的路径中所有点的点权和. 显然树链剖分可做 ...
- BZOJ 4034 树上操作(树的欧拉序列+线段树)
刷个清新的数据结构题爽一爽? 题意: 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个 操作,分为三种: 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x ...
- BZOJ 4034 [HAOI2015]树上操作(欧拉序+线段树)
题意: 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个 操作,分为三种: 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x 为根的子树中所有点的点权都增 ...
随机推荐
- poj3984迷宫问题(dfs+stack)
迷宫问题 Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 35426 Accepted: 20088 Descriptio ...
- centos下php环境安装redis
一.安装redis(仅可在服务器使用,尚不能通过浏览器访问) (1)首先下载redis:wget http://download.redis.io/releases/redis-4.0.9.tar.g ...
- git基础(1)
一.获取git仓库(两种方法)1.现有目录初始化 git init目录有文件(非空文件)进行跟踪执行:git add+文件名提交:git commit -m(提交信息说明) 2.克隆现有代码仓库的代码 ...
- 接口文档神器--apiui的使用
接口开发,最麻烦的就是写文档了,曾经我也因为写接口文档苦不堪言:自从使用了apiui接口文档神器,工作效率和文档清晰得到了不止一个档次的提升. 下面介绍一下这个神器的使用: 把文件下载下来,放在网站根 ...
- struts2源码分析-初始化流程
这一篇文章主要是记录struts.xml的初始化,还原struts2.xml的初始化流程.源码依据struts2-2.3.16.3版本. struts2初始化入口,位于web.xml中: <fi ...
- [leetcode-748-Largest Number At Least Twice of Others]
In a given integer array nums, there is always exactly one largest element. Find whether the largest ...
- SPOJ 8073 The area of the union of circles(计算几何の圆并)(CIRU)
Description You are given N circles and expected to calculate the area of the union of the circles ! ...
- js经典试题之数组与函数
js经典试题之数组与函数 1:列举js的全局函数? 答案:JavaScript 中包含以下 7 个全局函数escape( ).eval( ).isFinite( ).isNaN( ).parseFlo ...
- 蓝牙核心技术概述(四):蓝牙协议规范(HCI、L2CAP、SDP、RFOCMM)(转载)
一.主机控制接口协议 HCI 蓝牙主机-主机控模型 蓝牙软件协议栈堆的数据传输过程: 1.蓝牙控制器接口数据分组:指令分组.事件分组.数据分组(1).指令分组 如:Accpet Connection ...
- Internet Secure
key Secret key(密钥):ues the same key to Encryption and decryption(symmetric-key)对称加密,需要绝对安全的空间来传递key ...