没有什么能够阻挡,你对被阿的向往。天天 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. 请写一段 PHP 代码 ,确保多个进程同时写入同一个文件成功

    方案一: function writeData($filepath, $data) { $fp = fopen($filepath,'a'); do{ usleep(100); }while (!fl ...

  2. 怎样快捷获取元素节点body

    1. 使用: document.body document.body.nodeName; // "BODY" 2. 使用: document.getElementsByTagNam ...

  3. 第二讲,NT头文件格式,以及文件头格式

    今天详解NT 头格式,以及文件头格式,以及作用, 关于DOS头文件格式,以及DOSStub昨天的博客已经写过了.主要是分散讲解.便于理解. 一丶最小PE的生成,以及标准PE的生成 ps: (如果直接学 ...

  4. OpenCV安装和测试

    参考链接:http://blog.csdn.net/bruce_zeng/article/details/7961153 OpenCv下载链接:http://sourceforge.net/proje ...

  5. DPDK latencystats库使用方案

    初始化 注意务必调用 rte_metrics_init /* init latency stats */ /* @TODO should we remove this in product env? ...

  6. luogu1005矩阵取数游戏题解--区间DP

    题目链接 https://www.luogu.org/problemnew/show/P1005 分析 忽然发现这篇题解好像并没有什么意义...因为跟奶牛零食那道题一模一样,博主比较懒如果您想看题解的 ...

  7. vue学习(8)-过渡transition&动画animate

      进入之前                                                    离开之后 v-enter---v-enter-to            v-lea ...

  8. vue cli创建脚手架

    1.用vscode打开一个文件夹.在菜单栏 点击 查看-集成终端.这里可以用其他的方法比如cmd命令符调开这个界面,但是要用cd 切到要放文件的文件夹下. 2.安装好node.js  和淘宝镜像 3. ...

  9. 安装CDH5.11.2集群

    master  192.168.1.30 saver1  192.168.1.40 saver2  192.168.1.50 首先,时间同步 然后,ssh互通 接下来开始: 1.安装MySQL5.6. ...

  10. WPF实战案例-在线程内同步集合数据到UI线程

    有这样一个场景,在vm中,我们为了ui的体验,会异步访问后端接口,获取数据集合,如果这个集合绑定到界面,并且在线程内,怎么处理? 有人讲:this.Dispatcher.Invoke,如果在vm内呢? ...