就是让你求这个:

传送门:https://www.lydsy.com/JudgeOnline/problem.php?id=5394

解题思路:

NOIP2018后第一道题,感觉非常像那个上帝与集合的正确用法。

具体来说就是使用递归的求解方式,不过这次和上帝与集合的正确用法不同的是:

1.这次不是无限项,所以可以不在p=0时停止。

2.因为被取模数有限大,所以要特判小于φ(p)的情况。

3.询问时要预先处理φ(p)

代码:

 #include<cstdio>
#include<cstring>
#include<algorithm>
#define lll spc<<1
#define rrr spc<<1|1
#define maxval 20000000
typedef long long lnt;
struct trnt{
lnt val;
lnt lzt;
}tr[];
int prime[];
int eula[];
bool vis[];
int cnt;
int n,m;
lnt a[];
lnt read(void)
{
lnt ans=;
lnt f=;
char ch=getchar();
while(ch<''||ch>'')
{
if(ch=='-')
f=-f;
ch=getchar();
}
while(ch<=''&&ch>='')
{
ans=ans*10ll+(lnt)(ch-'');
ch=getchar();
}
return ans*f;
}
void Get_prime(void)
{
for(int i=;i<=maxval;i++)
{
if(!vis[i])
{
prime[++cnt]=i;
eula[i]=i-;
}
vis[i]=false;
for(int j=;j<=cnt&&(i*prime[j]<=maxval);j++)
{
vis[i*prime[j]]=true;
if(i%prime[j]==)
{
eula[i*prime[j]]=eula[i]*prime[j];
break;
}
eula[i*prime[j]]=eula[i]*(prime[j]-);
}
}
return ;
}
void Add(int spc,int l,int r,lnt v)
{
tr[spc].val+=v*(lnt)(r-l+);
tr[spc].lzt+=v;
return ;
}
void pushup(int spc)
{
tr[spc].val=tr[lll].val+tr[rrr].val;
return ;
}
void pushdown(int spc,int l,int r)
{
if(tr[spc].lzt)
{
int mid=(l+r)>>;
Add(lll,l,mid,tr[spc].lzt);
Add(rrr,mid+,r,tr[spc].lzt);
tr[spc].lzt=;
}
return ;
}
void build(int l,int r,int spc)
{
if(l==r)
{
tr[spc].val=a[l];
return ;
}
int mid=(l+r)>>;
build(l,mid,lll);
build(mid+,r,rrr);
pushup(spc);
return ;
}
void update(int l,int r,int ll,int rr,int spc,lnt v)
{
if(ll>r||l>rr)
return ;
if(ll<=l&&r<=rr)
{
Add(spc,l,r,v);
return ;
}
int mid=(l+r)>>;
pushdown(spc,l,r);
update(l,mid,ll,rr,lll,v);
update(mid+,r,ll,rr,rrr,v);
pushup(spc);
return ;
}
lnt query(int l,int r,int spc,int pos)
{
if(l==r)
return tr[spc].val;
int mid=(l+r)>>;
pushdown(spc,l,r);
if(pos<=mid)
return query(l,mid,lll,pos);
return query(mid+,r,rrr,pos);
}
lnt ksm(lnt a,lnt b,lnt mod,int plc)
{
lnt ans=;
while(b)
{
if(b&)
{
ans=ans*a;
if(ans>=mod)
{
ans%=mod;
vis[plc]=true;
}
}
a=a*a;
if(a>=mod)
{
a%=mod;
vis[plc]=true;
}
b/=;
}
return ans;
}
lnt Query(int l,int r,int p)
{
vis[l]=false;
lnt tmp=query(,n,,l);
if(tmp>=p)
vis[l]=true;
tmp%=p;
if(tmp==)
return ;
if(p==)
return ;
if(l==r)
return tmp%p;
lnt temp=eula[p];
return ksm(tmp,Query(l+,r,temp)+vis[l+]*temp,p,l);
}
int main()
{
Get_prime();
n=read();
m=read();
for(int i=;i<=n;i++)
a[i]=read();
build(,n,);
while(m--)
{
lnt cmd=read(),l=read(),r=read(),x=read();
if(cmd==)
update(,n,l,r,,x);
else
printf("%lld\n",Query(l,r,x));
}
return ;
}

BZOJ5394: [Ynoi2016]炸脖龙(欧拉广义降幂)的更多相关文章

  1. [洛谷P4118][Ynoi2016]炸脖龙I([洛谷P3934]Nephren Ruq Insania)

    题目大意:有$n$个数,每个数为$s_i$,两个操作: $1\;l\;r\;x:$表示将区间$[l,r]$内的数加上$x$ $2\;l\;r\;p:$表示求$s_l^{s_{l+1}^{^{s_{l+ ...

  2. BZOJ 5394 [Ynoi2016]炸脖龙 (线段树+拓展欧拉定理)

    题目大意:给你一个序列,需要支持区间修改,以及查询一段区间$a_{i}^{a_{i+1}^{a_{i+2}...}}mod\;p$的值,每次询问的$p$的值不同 对于区间修改,由线段树完成,没什么好说 ...

  3. P4118 [Ynoi2016]炸脖龙I

    思路:扩展欧拉定理 提交:\(\geq5\)次 错因:快速幂时刚开始没有判断\(a\)是否大于\(p\) 题解: 用树状数组维护差分,查询时暴力从左端点的第一个数向右端点递归,若递归时发现指数变为\( ...

  4. Luogu P4118 [Ynoi2016]炸脖龙I

    题目 首先考虑没有修改的情况.显然直接暴力扩展欧拉定理就行了,单次复杂度为\(O(\log p)\)的. 现在有了修改,我们可以树状数组维护差分数组,然后\(O(\log n)\)地单次查询单点值. ...

  5. Uva 10129 - Play on Words 单词接龙 欧拉道路应用

    跟Uva 10054很像,不过这题的单词是不能反向的,所以是有向图,判断欧拉道路. 关于欧拉道路(from Titanium大神): 判断有向图是否有欧拉路 1.判断有向图的基图(即有向图转化为无向图 ...

  6. FZU 1759 欧拉函数 降幂公式

    Description   Given A,B,C, You should quickly calculate the result of A^B mod C. (1<=A,C<=1000 ...

  7. HDU 3221 矩阵快速幂+欧拉函数+降幂公式降幂

    装载自:http://www.cnblogs.com/183zyz/archive/2012/05/11/2495401.html 题目让求一个函数调用了多少次.公式比较好推.f[n] = f[n-1 ...

  8. FZU Super A^B mod C(欧拉函数降幂)

    Problem 1759 Super A^B mod C Accept: 878    Submit: 2870 Time Limit: 1000 mSec    Memory Limit : 327 ...

  9. ACM-数论-广义欧拉降幂

    https://www.cnblogs.com/31415926535x/p/11447033.html 曾今一时的懒,造就今日的泪 记得半年前去武大参加的省赛,当时的A题就是一个广义欧拉降幂的板子题 ...

随机推荐

  1. 计数排序、桶排序python实现

    计数排序在输入n个0到k之间的整数时,时间复杂度最好情况下为O(n+k),最坏情况下为O(n+k),平均情况为O(n+k),空间复杂度为O(n+k),计数排序是稳定的排序. 桶排序在输入N个数据有M个 ...

  2. AES加密解密在JAVA和ANDROID下互通

    <span style="font-family: Arial, Helvetica, sans-serif;">昨天外包安卓的那个人说AES的加解密结果不一样.于是百 ...

  3. 无法往SQL Server Management Studio拖脚本

    解决方法:不要用Administrator权限打开sql server

  4. jquery easyui 输入框 禁止输入负数 设置属性data-options="min:0,required:true"

    jquery easyui  输入框 禁止输入负数  设置属性data-options="min:0,required:true" <input id="days& ...

  5. Python正则表达式初识(八)

    继续分享Python正则表达式的基础知识,今天给大家分享的特殊字符是“\w”和“\W”,具体的教程如下. 1.“\w”代表的意思是该字符为任意字符,但是和特殊字符“.”的意思不同.“\w”代表的字符主 ...

  6. Java基础String的方法

    Java基础String的方法 字符串类型写法格式如下: 格式一: String 变量名称; 变量名称=赋值(自定义或传入的变量值); 格式二: String 变量名称=赋值(自定义或传入的变量值); ...

  7. tac---反转输出文件

    tac命令用于将文件已行为单位的反序输出,即第一行最后显示,最后一行先显示.

  8. Centos6.5 安装lnmp环境

    最近项目要配置在nginx上,所以搜索了下具体nginx的安装,看到这篇文章简洁明了而且测试成功就借用了,作品出处:http://www.cnblogs.com/xiaoit/p/3991037.ht ...

  9. CodeForcesGym 100502G Outing

    Outing Time Limit: 1000ms Memory Limit: 524288KB This problem will be judged on CodeForcesGym. Origi ...

  10. JAVA学习第五十四课 — IO流(八)打印流 &amp; 序列流

    一.综合练习-文件清单列表 获取指定文件夹下,指定扩展名的文件(含子文件夹),并将这些文件的绝对路径写到一个文本文件里.也就是建立一个指定扩展名的文件列表 1.深度遍历 2.过滤器->容器 3. ...