没有什么能够阻挡,你对被阿的向往。天天 AK 的生涯,你的心了无牵挂。 虐过大佬的比赛,也曾装弱装逼。当你低头的瞬间,才发现旁边的人。 把你的四肢抬起来,使劲地往门上撞。盛开着永不凋零,黑莲花。 ——cx & cyx《黑莲花》

  这是一道数论题。

  

T3

请此题爆零的同学写一份心得体会,明天交给我。

对于区间修改,将原数组差分之后使用树状数组即可。

首先要知道扩展欧拉定理:对于任意的正整数a和p,且b≥φ(p),有:

扩展欧拉定理的一个重要应用就是降幂

而对于询问区间[l,r] mod p(其询问结果记作s(l,r,p)),可以推出:

(假设上式中出现的模p意义下的幂指数都大于等于φ(p))

将p不断地变成φ(p)需要O(log p)次之后p变成1。

而指数为1可以直接计算。

所以询问s(l,r,p)可以递归做:

(1)如果l=r或者p=1则直接反回a[l]。

(2)否则递归到s(l+1,r,φ(p)),记其为t。如果t≥φ(p)则返回

,否则反回

剩下一个问题:如何判断指数是否大于等于φ(p)。

注意到。

所以,我们只需要取出[l+1,r]的前5个数(如果[l+1,r]的区间长度不足5则取区间[l+1,r]内所有数,如果[l+1,r]内第一个1出现的位置为x则取[l+1,x-1]内所有数)

如果取出的数的个数为5则一定大于φ(p)。否则可以大力快速幂判断指数是否大于等于φ(p)。

可以用线性的欧拉筛预处理欧拉函数。

复杂度。

实测:开O2优化并且使用普通读入优化:5.8s;使用fread:3.4s。

良心搬题人为了防止卡常,开到了9s。

这是一道数据结构与数论结合的好题。

代码:

#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cmath>
#define int long long
const int N = 20001000;
using namespace std;
inline int read()
{
int x = 0 , f = 1; char ch = getchar();
while(ch < '0' || ch > '9') {if(ch == '-') f = -1; ch = getchar();}
while(ch >= '0' && ch <= '9') {x = (x << 3) + (x << 1) + (ch ^ 48); ch = getchar();}
return x * f;
}
int phi[N],ans,a[N],cnt,prime[N];
int n,m,opt,l,r,p;
bool vis[N],flag;
void yilin()
{
phi[1]=1;
vis[1] = 1;
for(int i=2;i<=20000000;i++)
{
if(!vis[i])prime[++cnt]=i , phi[i] = i - 1;
for(int j=1;j<=cnt && i * prime[j] <= 20000000;j++)
{
vis[i*prime[j]]=1;
if(i%prime[j]==0)
{
phi[i*prime[j]]=phi[i] * prime[j];
break;
}
phi[i*prime[j]]=phi[i] * (prime[j]-1);
}
}
}
//////////////////////用线段树处理区间加,单点查询
int tr[N<<1],lazy[N<<1];
void build(int k,int l,int r)
{
if(l==r)
{
tr[k]=a[l];
return;
}
int mid=(l+r)>>1;
build(k<<1,l,mid);
build(k<<1|1,mid+1,r);
}
void pushdown(int k,int l,int r)
{
tr[k<<1] = tr[k<<1]+lazy[k];
tr[k<<1|1] = tr[k<<1|1]+lazy[k];
lazy[k<<1] = lazy[k];
lazy[k<<1|1] = lazy[k];
lazy[k] = 0;
}
void change(int k,int l,int r,int x,int y,int val)
{
if(x<=l && y>=r)
{
lazy[k]+=val;
tr[k]+=(r-l+1)*val;
return ;
}
if(lazy[k]) pushdown(k,l,r);
int mid=(l+r) >> 1;
if(x<=mid)change(k<<1,l,mid,x,y,val);
if(y>mid)change(k<<1|1,mid+1,r,x,y,val);
}
int ask(int k,int l,int r,int x,int y)
{
if(l>=x&&r<=y){return tr[k];}
if(lazy[k]) pushdown(k,l,r);
int mid=(l+r) >> 1;
if(x<=mid) return ask(k<<1,l,mid,x,y);
if(y>mid) return ask(k<<1|1,mid+1,r,x,y);
}
/////////////////////////
c
b
a
int ksm(int x,int y,int p)////快速幂
{
int res=1;
if(x >= p) flag=1,x%=p;相当于b 如果b 比p大,那么b的某一次方一定也比p大,这样才符合公式
for(;y;y>>=1)
{
if(y&1)res=res*x;
if(res >= p) flag = true, res %= p;////快速幂,如果当前处理的值比p大,记录一下,之后才能取模,如果直接模,一直会比p小
x=(x * x);
if(x >= p) flag = true, x %= p;
}
return res;////不及取模,影响后面对于和p 的判断
}
int solve (int l,int r,int p)
{
// printf("%lld\n",ask(1,1,n,l,l));
if(l == r) return ask(1,1,n,l,l);
if(p == 1) return ask(1,1,n,l,l);
int t=solve(l+1,r,phi[p]);
if(t > phi[p] || flag) t = t % phi[p] +phi[p] , flag=false;
int ans = ksm( ask(1,1,n,l,l) , t , p);
return ans;
}
signed main()
{
#ifdef yilnr
#else
freopen("zzq.in","r",stdin);
freopen("zzq.out","w",stdout);
#endif
n=read(); m=read();
for(int i=1;i<=n;i++)a[i]=read();
build(1,1,n);
yilin();////线性筛欧拉函数
for(int i=1;i<=m;i++)
{
opt=read();l=read();r=read();p=read();
if(opt==1)
{
change(1,1,n,l,r,p);
}
if(opt==2)
{
flag=false;////对于每次操作,要先把flag 赋值为0 ,因为此次操作与之前无关,需重新判断;
printf("%lld\n",solve(l,r,p)%p );
}
}
fclose(stdin);fclose(stdout);
return 0;
}

  

【csp模拟赛2】黑莲花--数据结构+数论的更多相关文章

  1. CSP模拟赛游记

    时间:2019.10.5 考试时间:100分钟(连正式考试时间的一半还没有到)题目:由于某些原因不能公开. 由于第一次接触NOIinux系统所以连怎么建文件夹,调字体,如何编译都不知道,考试的前半小时 ...

  2. 【NOIP模拟赛】飞(fly) 数论+树状数组

    树状数组一个被发明以来广为流行的数据结构,基于数组,核心是lowerbit()操作.他向前lowerbit()操作为前缀,向后lowerbit()操作为上辖,我们运用树状数组都是使一个由O(1)变为O ...

  3. 【CSP模拟赛】Freda的迷宫(桥)

    题目描述 Freda是一个迷宫爱好者,她利用业余时间建造了许多迷宫.每个迷宫都是由若干房间和走廊构成的,每条走廊都连接着两个不同的房间,两个房间之间最多只有一条走廊直接相连,走廊都是双向通过.  黄昏 ...

  4. CSP模拟赛3游记

    老师说这次题比较难,深表同意,还是只有90min. T1有还几个坑点,呜呜呜,感觉有点像斗地主的超级简化版. T2:不难但是特别复杂需要70+行代码,比龙虎斗好想但比较难写,但还是成功打挂. T3:根 ...

  5. CSP模拟赛2游记

    这次由于有课迟到30min,了所以只考了70min. 调linux配置调了5min,只剩下65min了. T1:有点像标题统计,但要比他坑一点,而且我就被坑了,写了一个for(int i=1;i< ...

  6. 【CSP模拟赛】Freda的旗帜

    题目描述  要开运动会了,Freda承担起了制作全校旗帜的工作.旗帜的制作方法是这样的:Freda一共有C种颜色的布条,每种布条都有无数个,你可以认为这些布条的长.宽.厚都相等,只有颜色可能不同.每个 ...

  7. 【csp模拟赛4】基站建设 (station.cpp)

    [题目描述] 小 Z 的爸爸是一位通信工程师,他所在的通信公司最近接到了一个新的通 信工程建设任务,他们需要在 C 城建设一批新的基站. C 城的城市规划做得非常好,整个城市被规整地划分为 8 行 8 ...

  8. 【CSP模拟赛】starway(玄学建边 最小生成树)

    问題描述 小w伤心的走上了 Star way to heaven.   到天堂的道路是一个笛卡尔坐标系上一个n×m的长方形通道(顶点在(0,0))和(n,m)),小w从最左边任意一点进入,从右边任意一 ...

  9. 【CSP模拟赛】Confess(数学 玄学)

    题目描述 小w隐藏的心绪已经难以再隐藏下去了.小w有n+ 1(保证n为偶数)个心绪,每个都包含了[1,2n]的一个大小为n的子集.现在他要找到隐藏的任意两个心绪,使得他们的交大于等于n/2. 输入描述 ...

随机推荐

  1. python 安装virtualenv和wxPython

    有人说 Virtualenv.Fabric 和 PIP 是 Pythoneer 的三大神器 上一节说过了怎么安装PIP,下面继续安装virtualenv 安装wxPython时比较简单 sudo pi ...

  2. Python--类的调用

    类的调用 实例化 class Luffy: school = 'luffy' def __init__(self,name,age): self.Name = name self.Age = age ...

  3. zookeeper客户端KeeperErrorCode = ConnectionLoss异常问题排查历险记

    经过线报,说前方应用有异常,导致了可用性变差.咦!讨厌的异常,抛异常是程序猿最讨厌的事情之一. 经过收集异常信息如下 ​ ​ 2019-06-24 10:57:41.806 ERROR [hades- ...

  4. MySql字段类型及字节

    字段类型:TINYINT-----------------一个很小的整数.有符号的范围是-128到127,无符号的范围是0到255. SMALLINT--------------一个小整数.有符号的范 ...

  5. git提交项目到码云

    提交代码: git initgit remote add origin 远程仓库地址git pull --rebase origin mastergit add -Agit commit -m &qu ...

  6. C# 委托 、事件、同步、异步知识点归纳

    一.委托 基本用法: 1.声明一个委托类型.委托就像是‘类'一样,声明了一种委托之后就可以创建多个具有此种特征的委托.(特征,指的是返回值.参数类型) public delegate void Som ...

  7. 获取windows进程信息及CListCtrl控件(List Control)练习

    环境:VS2010/MFC/对话框 效果图: 目录: 1.  关于windows进程信息获取 2.  CListCtrl的使用 ------------------------------------ ...

  8. [转载]机器学习优化方法总结:SGD,Momentum,AdaGrad,RMSProp,Adam

    [转载]机器学习优化方法总结:SGD,Momentum,AdaGrad,RMSProp,Adam https://blog.csdn.net/u010089444/article/details/76 ...

  9. luogu P3750 [六省联考2017]分手是祝愿

    luogu loj 可以发现在最优策略中,每种操作最多只会做一次,并且操作的先后顺序并不会影响答案,所以考虑从后往前扫,碰到一个\(1\)就对这个位置\(i\)进行操作,这样的操作一定是最优策略.记最 ...

  10. 关于阮一峰老师es6(第三版)中管道机制代码的理解浅析

    最近正在学习阮一峰老师的es6(第三版)教材,在学到第七章<函数的扩展>中的箭头函数嵌套时,文中提到了一个关于“管道机制”的示例,文中源代码如下: //es6(第三版)教材中的管道机制源代 ...