[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 为根的子树中所有点的点权都增 ...
随机推荐
- Java子类与父类之间的类型转换
1.向上转换 父类的引用变量指向子类变量时,子类对象向父类对象向上转换.从子类向父类的转换不需要什么限制,只需直接蒋子类实例赋值给父类变量即可,这也是Java中多态的实现机制. 2.向下转换 在父类变 ...
- Kubernetes 在网易云中的落地优化实践
本文来自网易云社区 今天我跟大家讲的是 Kubernetes 在网易的一些实践,目的是抛砖引玉,看看大家在这个方向有没有更好的实践方法.简单介绍一下网易云.网易云是从最早 Kubernetes 1.0 ...
- Django学习总结- ③
对象属性与继承关系: 对象属性 1. 显示属性 - 开发者手动定义的,直接看的到的 2. 隐式属性 - 系统根据需求,自动创建的对象 - objects 它是model.Manager对象 - 当我们 ...
- hive使用spark引擎的几种情况
使用spark引擎查询hive有以下几种方式:1>使用spark-sql(spark sql cli)2>使用spark-thrift提交查询sql3>使用hive on spark ...
- Y460蓝牙键盘无法连接问题解决
mac坏了,无法启动,一直没时间去修理. 近期把大学的时候用的笔记本又翻了出来,小Y,经典的“娱乐本” Y460. Y460上之前被自己各种重装系统,反复从windows到双系统,再到linux之间来 ...
- Netcore logging config
- Pandas dataframe数据写入文件和数据库
转自:http://www.dcharm.com/?p=584 Pandas是Python下一个开源数据分析的库,它提供的数据结构DataFrame极大的简化了数据分析过程中一些繁琐操作,DataFr ...
- 第一、二章——Python简介与Python基础
前言:<Data Wrangling with Python>这本书主要是讲使用Pyhon来处理各种类型保存的数据的. 第一章:Python简介 1.版本选择 本书选择的Python版本是 ...
- LintCode-532.逆序对
逆序对 在数组中的两个数字如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对.给你一个数组,求出这个数组中逆序对的总数. 概括:如果a[i] > a[j] 且 i < j, a[i ...
- iOS- 优化与封装 APP音效的播放
1.关于音效 音效又称短音频,是一个声音文件,在应用程序中起到点缀效果,用于提升应用程序的整体用户体验. 我们手机里常见的APP几乎都少不了音效的点缀. 显示实现音效并不复杂,但对我们App很 ...