没有什么能够阻挡,你对被阿的向往。天天 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. Photon Server初识(四) --- 部署自己的服务Photon Server

    准备工作: 1.一台 window 虚拟机(本机是window也行) 2.下载SDK : https://www.photonengine.com/zh-CN/sdks#server 一:SDK介绍 ...

  2. select key from table 一直出错

    key和keys  为mysql 关键字,数据库设计字段的时候尽量避免

  3. Python 常用外部模块详解

    Python 的创始人为吉多·范罗苏姆(Guido van Rossum).1989年的圣诞节期间,吉多·范罗苏姆为了在阿姆斯特丹打发时间,决心开发一个新的脚本解释程序,作为ABC语言的一种继承.Py ...

  4. 牛客 203B tree(树形dp)

    大意: 给定树, 对于每个节点, 求包含该节点的连通子集数. 显然有$dp[x]=\prod (dp[y]+1), ans[x]=(\frac{ans[fa[x]]}{dp[x]+1}+1)dp[x] ...

  5. C#字典转对象

    /// <summary> /// Assign parameters to specified objects /// </summary> /// <typepara ...

  6. StoneTab标签页CAD插件 3.2.3

    //////////////////////////////////////////////////////////////////////////////////////////////////// ...

  7. python selenium5 模拟点击+拖动+按照指定相对坐标拖动 58同城验证码

    #!/usr/bin/python # -*- coding: UTF-8 -*- # @Time : 2019年12月9日11:41:08 # @Author : shenghao/10347899 ...

  8. javaIO——PipedReader 和 PipedWriter 实现模拟即时聊天

    上一篇学习了javaIO里面的 PipedReader 和 PipedWriter,这里对两个类做一个小小的练习:实现一个即时消息发送和接收的聊天系统(这里只实现单向发送,双向同理,定义两个管道即可) ...

  9. 销售订单(SO)-API-创建销售订单

    创建销售订单API主要注意几点: 初始化环境变量:fnd_global.apps_initialize(); mo_global.init('ONT'); mo_global.set_policy_c ...

  10. IPhone中H5页面用on绑定click无效的解决方法

    首先声明本人资质尚浅,本文只用于个人总结.如有错误,欢迎指正.共同提高. --------------------------------------------------------------- ...