BZOJ5394: [Ynoi2016]炸脖龙(欧拉广义降幂)
就是让你求这个:

传送门: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]炸脖龙(欧拉广义降幂)的更多相关文章
- [洛谷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+ ...
- BZOJ 5394 [Ynoi2016]炸脖龙 (线段树+拓展欧拉定理)
题目大意:给你一个序列,需要支持区间修改,以及查询一段区间$a_{i}^{a_{i+1}^{a_{i+2}...}}mod\;p$的值,每次询问的$p$的值不同 对于区间修改,由线段树完成,没什么好说 ...
- P4118 [Ynoi2016]炸脖龙I
思路:扩展欧拉定理 提交:\(\geq5\)次 错因:快速幂时刚开始没有判断\(a\)是否大于\(p\) 题解: 用树状数组维护差分,查询时暴力从左端点的第一个数向右端点递归,若递归时发现指数变为\( ...
- Luogu P4118 [Ynoi2016]炸脖龙I
题目 首先考虑没有修改的情况.显然直接暴力扩展欧拉定理就行了,单次复杂度为\(O(\log p)\)的. 现在有了修改,我们可以树状数组维护差分数组,然后\(O(\log n)\)地单次查询单点值. ...
- Uva 10129 - Play on Words 单词接龙 欧拉道路应用
跟Uva 10054很像,不过这题的单词是不能反向的,所以是有向图,判断欧拉道路. 关于欧拉道路(from Titanium大神): 判断有向图是否有欧拉路 1.判断有向图的基图(即有向图转化为无向图 ...
- FZU 1759 欧拉函数 降幂公式
Description Given A,B,C, You should quickly calculate the result of A^B mod C. (1<=A,C<=1000 ...
- HDU 3221 矩阵快速幂+欧拉函数+降幂公式降幂
装载自:http://www.cnblogs.com/183zyz/archive/2012/05/11/2495401.html 题目让求一个函数调用了多少次.公式比较好推.f[n] = f[n-1 ...
- FZU Super A^B mod C(欧拉函数降幂)
Problem 1759 Super A^B mod C Accept: 878 Submit: 2870 Time Limit: 1000 mSec Memory Limit : 327 ...
- ACM-数论-广义欧拉降幂
https://www.cnblogs.com/31415926535x/p/11447033.html 曾今一时的懒,造就今日的泪 记得半年前去武大参加的省赛,当时的A题就是一个广义欧拉降幂的板子题 ...
随机推荐
- Mac系统下安装ant
看了一些别人怎么在mac下安装ant,大体都是从官网下载bin文件,然后改动权限,建链接.配path. 须要这么麻烦吗?我认为不须要. 以下一个命令搞定: forlong401:build forlo ...
- 计数排序、桶排序python实现
计数排序在输入n个0到k之间的整数时,时间复杂度最好情况下为O(n+k),最坏情况下为O(n+k),平均情况为O(n+k),空间复杂度为O(n+k),计数排序是稳定的排序. 桶排序在输入N个数据有M个 ...
- Whats the difference between git reset --mixed, --soft, and --hard?
https://stackoverflow.com/questions/3528245/whats-the-difference-between-git-reset-mixed-soft-and-ha ...
- 关于commJS 和 es6 的一些区别
CommonJS模块与ES6模块的区别 本文转自 https://www.cnblogs.com/unclekeith/archive/2017/10/17/7679503.html CommonJS ...
- Python正则表达式初识(五)
正则表达式的内容很丰富,今天小编继续给大家分享Python正则表达式的基础知识.今天要给大家的讲的特殊字符是竖线“|”.竖线“|”实质上是一个或的关系. 1.直接上代码演示,比方说我们需要匹配一个字符 ...
- Scrapy发送POST请求
一.发送post请求需要将start_urls注释,然后重写start_requests方法二.使用yield scrapy.FormRequest(url=post_url, formdata=fo ...
- 紫书 例题 9-11 UVa 1331 (最优三角形剖分)
设置f(i, j)为点i, i + 1 --j所组成的多边形. 那么可以枚举中间点k, 得f(i, j) = min{s(i, j, k), f(i, k), f(k, j) | i < k & ...
- boost.property_tree的高级用法(你们没见过的操作)
版权声明:本文为博主原创文章,未经博主允许不得转载. 前一阵写项目,终于将这个boost下的xml读取类完成了,由于网上对property_trees的讲解很少,最多也就到get_child这个层面, ...
- ubuntu下vim中内容拷贝到浏览器
在vim中编辑好了代码想要复制出来到浏览器或者其它地方.用yy复制后去别的地方粘帖发现根本不是当初复制的内容,非常头疼-- 这是由于vim中有它自己的一套剪贴板系统(clipboard).这套系统和u ...
- matlab中tic和toc使用方法
tic和toc用来记录matlab命令运行的时间. tic用来保存当前时间,而后使用toc来记录程序完毕时间. 两者往往结合使用,使用方法例如以下: 程序代码: tic operations t ...