【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. 输入描述 ...
随机推荐
- Pygame小游戏练习四
@Python编程从入门到实践 Python项目练习 九.添加Play按钮 一.创建Button类 先让游戏一开始为非活动状态 # game_stats.py # --snip-- self.game ...
- 【AC自动机】文本生成器
[题目链接] https://loj.ac/problem/10063 [题意] 给出长度为m,n个模式串,请问只要长度为m的串中有一个模式串就算是可读. [分析] 其实如果直接分析全部可读的情况,一 ...
- springboot加载application.yml文件null
话不多说,直接上代码 本人项目为maven项目 以下是项目结构 pom.xml文件 <?xml version="1.0" encoding="UTF-8" ...
- CCF - CCSP 2018-01 绝地求生 BFS
BFS从安全地区方向搞一下就好了 1.还是注意每回合清空 2.posx居然开小了,可不能犯这种错误 3.地图用a和节点的dis重名了,建议其他变量禁止用a命名 4.在输入数据之前continue了,这 ...
- 判断两个list是否元素一样
首先创建枚举 public enum TheType { type1 = , type2 = , type3 = } 1.如果不考虑顺序,即顺序不一样,只要元素都一样即可 List<TheTyp ...
- 使用Seaborn展示多变量两两之间的关系
数据展示: 1. FacetGrid FacetGrid是一个储存我们想怎样展示信息的东西,如下所示,我们想观察位置中SK和GK的分布. 在这里我们使用map方法把数据填充到图表中 计算类别在某一特征 ...
- 用表格制作商品购买页面--(table)
实现效果如图: 首先来看布局,头部图片,内容从左到右分为四个部分 勾选+商品图片+商品名/买家+价格, 所以需要将头部用<td>包括起来,并且设置<td colspan=&quo ...
- js-回文数
回文数 设n是一任意自然数.若将n的各位数字反向排列所得自然数n1与n相等,则称n为一回文数. //回文数 let readline = require("readline-sync&quo ...
- 【异常】 Could not find Linker 'g++' in system path.
1 详细异常 FAILURE: Build failed with an exception. * What went wrong: Execution failed for task ':az-ex ...
- 原生js为页面添加爱心特效和判断手机端还是电脑端登录
<!-- 为页面添加爱心特效 --> <script type="text/javascript"> (function (window, document ...