【csp模拟赛2】黑莲花--数据结构+数论
没有什么能够阻挡,你对被阿的向往。天天 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】黑莲花--数据结构+数论的更多相关文章
- CSP模拟赛游记
时间:2019.10.5 考试时间:100分钟(连正式考试时间的一半还没有到)题目:由于某些原因不能公开. 由于第一次接触NOIinux系统所以连怎么建文件夹,调字体,如何编译都不知道,考试的前半小时 ...
- 【NOIP模拟赛】飞(fly) 数论+树状数组
树状数组一个被发明以来广为流行的数据结构,基于数组,核心是lowerbit()操作.他向前lowerbit()操作为前缀,向后lowerbit()操作为上辖,我们运用树状数组都是使一个由O(1)变为O ...
- 【CSP模拟赛】Freda的迷宫(桥)
题目描述 Freda是一个迷宫爱好者,她利用业余时间建造了许多迷宫.每个迷宫都是由若干房间和走廊构成的,每条走廊都连接着两个不同的房间,两个房间之间最多只有一条走廊直接相连,走廊都是双向通过. 黄昏 ...
- CSP模拟赛3游记
老师说这次题比较难,深表同意,还是只有90min. T1有还几个坑点,呜呜呜,感觉有点像斗地主的超级简化版. T2:不难但是特别复杂需要70+行代码,比龙虎斗好想但比较难写,但还是成功打挂. T3:根 ...
- CSP模拟赛2游记
这次由于有课迟到30min,了所以只考了70min. 调linux配置调了5min,只剩下65min了. T1:有点像标题统计,但要比他坑一点,而且我就被坑了,写了一个for(int i=1;i< ...
- 【CSP模拟赛】Freda的旗帜
题目描述 要开运动会了,Freda承担起了制作全校旗帜的工作.旗帜的制作方法是这样的:Freda一共有C种颜色的布条,每种布条都有无数个,你可以认为这些布条的长.宽.厚都相等,只有颜色可能不同.每个 ...
- 【csp模拟赛4】基站建设 (station.cpp)
[题目描述] 小 Z 的爸爸是一位通信工程师,他所在的通信公司最近接到了一个新的通 信工程建设任务,他们需要在 C 城建设一批新的基站. C 城的城市规划做得非常好,整个城市被规整地划分为 8 行 8 ...
- 【CSP模拟赛】starway(玄学建边 最小生成树)
问題描述 小w伤心的走上了 Star way to heaven. 到天堂的道路是一个笛卡尔坐标系上一个n×m的长方形通道(顶点在(0,0))和(n,m)),小w从最左边任意一点进入,从右边任意一 ...
- 【CSP模拟赛】Confess(数学 玄学)
题目描述 小w隐藏的心绪已经难以再隐藏下去了.小w有n+ 1(保证n为偶数)个心绪,每个都包含了[1,2n]的一个大小为n的子集.现在他要找到隐藏的任意两个心绪,使得他们的交大于等于n/2. 输入描述 ...
随机推荐
- 第六章 ZYNQ-MIZ701 GPIO使用之MIO
6.0 本章难度系数★★☆☆☆☆☆ 6.1 GPIO简介 Zynq7000系列芯片有54个MIO(multiuse I/O),它们分配在 GPIO 的Bank0 和Bank1隶属于PS部分,这些I ...
- C#向远程地址发送数据
static string proxyIpAddress = AppConfig.GetProxyIpAddress; static string proxyUserName = AppConfig. ...
- [http]HTTP状态码含义
HTTP状态码 当浏览者访问一个网页时,浏览者的浏览器会向网页所在服务器发出请求.当浏览器接收并显示网页前,此网页所在的服务器会返回一个包含HTTP状态码的信息头(server header)用以响应 ...
- windows服务与log4net应用
有时候我们需要用到window服务来执行定时任务,然后配合log4net记录程序运行情况,这里简单记录下配置的整个过程以及注意要点: 一.添加windows服务 1.设计页面,右键添加安装程序
- js之数据类型(对象类型——单体内置对象——Math)
Math是一个内置对象,它具有数学常数和函数的属性和方法.Math对象用于执行数学任务,和其它对象不同,Math只是一个静态对象并没有Math()构造函数,实际上,Math()只是一个由js设置的对象 ...
- LLVM使用其他Pass的结果
之前的工作一直集中在clang中,最近有点空闲时间,又重新熟悉了一下Pass的书写过程.(参考LLVM CookBook和http://llvm.org/docs/WritingAnLLVMPass. ...
- python之atexit模块的使用
python atexit 模块定义了一个 register 函数,用于在 python 解释器中注册一个退出函数,这个函数在解释器正常终止时自动执行,一般用来做一些资源清理的操作. atexit 按 ...
- 【异常】warning: refname 'feature1.3.0' is ambiguous.导致git merge失败
1 现象 自己git merge --no-ff feature1.3.0 无法合并代码到develop,代码还是停留在feature1.3.0的分支 并提示一下错误 warning: refname ...
- 在SqlServer和Oralce中创建索引
给表名A的字段A增加索引 SqlServer: if exists (select 1 from sysobjects where name='表名A' and type='u')and exists ...
- C#DataGrid列值出现E形式的小数,将DataGrid表格上的数据保存至数据库表时会因格式转换不正确导致报错
问题描述:在DataGridView中调整金额一列,当输入小数0.000001后会显示1E-6,此时进行保存操作时报错,提示无法将string类型转换成Decimal 原因分析:由于列调整金额为1E- ...