[Ynoi2015]此时此刻的光辉
题目大意:
给定一个序列,每次询问一段区间的数的乘积的约数个数。
解题思路:
在太阳西斜的这个世界里,置身天上之森。等这场战争结束之后,不归之人与望眼欲穿的众人, 人人本着正义之名,长存不灭的过去、逐渐消逝的未来。我回来了,纵使日薄西山,即便看不到未来,此时此刻的光辉,盼君勿忘。————世界上最幸福的女孩
我永远喜欢珂朵莉。
---
\(10^9\)以内的数最多有10个不同的质因子。
考虑对其质因数分解。
由于值域范围过大,考虑使用Pollard-Rho算法。
这里普通的Pollard-Rho算法可能会TLE。如果你的代码能通过模板题,那基本上没问题(窝反正直接把以前写的板子拉过来然后调了调参)。
之后,你就会得到最多\(10n\)个不同的质因数。对其进行离散化,开桶记录。
然后上莫队,对于每次指针的偏移,把它所有的质因数加到桶里,同时维护约数个数即可。
这部分时间复杂度\(O(10n\sqrt n)\),加上上面的质因数分解的玄学期望复杂度,只能获得82分的好成绩。
---
我们考虑把每个数\(1000\)以内的质因子先取出来(\(1000\)以内共168个质数),然后,对其做前缀和,记录前缀的出现次数。
然后,由于\(1001^3>10^9\),所以每个数剩下最多不超过2个质因子。这部分用Pollard_Rho找即可。
然后莫队的时候,对于前面168个质数就可以不用维护,直接用前缀和。
而对于后面的大质因子,再离散化处理即可。由于每个数最多两个质因子,所以常数就小了很多。
而由于筛掉了很多小的质因子,Pollard_Rho的速度也会变快。然后就足以通过此题。
C++ Code:
#include<cctype>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<vector>
#include<cstring>
#define ctz __builtin_ctz
using namespace std;
#ifdef ONLINE_JUDGE
struct istream{
char buf[23333333],*s;
inline istream(){
buf[fread(s=buf,1,23333330,stdin)]='\n';
fclose(stdin);
}
inline istream&operator>>(int&d){
d=0;
for(;!isdigit(*s);++s);
while(isdigit(*s))
d=(d<<3)+(d<<1)+(*s++^'0');
return*this;
}
}cin;
struct ostream{
char buf[8000005],*s;
inline ostream(){s=buf;}
inline ostream&operator<<(int d){
if(!d){
*s++='0';
}else{
static int w;
for(w=1;w<=d;w*=10);
for(;w/=10;d%=w)*s++=d/w^'0';
}
return*this;
}
inline ostream&operator<<(const char&c){*s++=c;return*this;}
inline void flush(){
fwrite(buf,1,s-buf,stdout);
s=buf;
}
inline~ostream(){flush();}
}cout;
#else
#include<iostream>
#endif
int pri[170],cct=0,sum[100005][169],num[1005];
void sieve(){
for(int i=2;i<=1000;++i)num[i]=1;
for(int i=2;i<=1000;++i)
if(num[i]){
pri[num[i]=++cct]=i;
for(int j=i<<1;j<=1000;j+=i)num[j]=0;
}
}
using LoveLive=long long;
vector<int>tj;
const int pr[]={2,3,5,24251,61,19260817};
int gcd(int a,int b){
if(!a||!b)return a|b;
int t=ctz(a|b);
a>>=ctz(a);
do{
b>>=ctz(b);
if(a>b)swap(a,b);
b-=a;
}while(b);
return a<<t;
}
inline int power(int a,int b,const int&md){
int ans=1;
for(;b;b>>=1){
if(b&1)ans=(LoveLive)ans*a%md;
a=(LoveLive)a*a%md;
}
return ans;
}
int miller_rabin(int p){
if(p==2)return 1;
int b=p-1;
int t=0;
while(!(b&1))b>>=1,++t;
for(int i:pr){
int r=power(i%(p-2)+2,b,p);
if(r==1||r==p-1)continue;
int ok=1;
for(int j=1;j<=t&&ok;++j){
r=(LoveLive)r*r%p;
if(r==p-1)ok=0;
}
if(ok)return 0;
}
return 1;
}
void pollard_rho(int&n,int c){
int k=2,x=rand()%(n-1)+1,y=x,q=1,t=1;
for(;;k<<=1,y=x,q=1){
for(int i=1;i<=k;++i){
x=((LoveLive)x*x%n+c)%n;
q=(LoveLive)q*abs(x-y)%n;
if(!(i&63)){
t=gcd(q,n);
if(t>1)break;
}
}
if(t>1||(t=gcd(q,n))>1)break;
}
n=t;
}
void find(int n,int c){
if(n==1)return;
if(miller_rabin(n)){tj.push_back(n);return;}
int p=n;
while(p>=n)pollard_rho(p,c--);
n/=p;
tj.push_back(n),tj.push_back(p);
}
#define N 100005
const int md=19260817;
int n,m,a[N],inv[N],cnt[N],tot[N*2],now=1,ans[N];
int p[N][3];
vector<int>lr;
struct que{
static const int siz=317;
int l,r,id;
inline bool operator<(const que&rhs)const{
return((l/siz!=rhs.l/siz)?(l<rhs.l):r<rhs.r);
}
}q[N];
inline void add(int id){
for(register int i=1;i<=cnt[id];++i)
now=(LoveLive)now*inv[tot[p[id][i]]]%md*(tot[p[id][i]]+1)%md,++tot[p[id][i]];
}
inline void del(int id){
for(register int i=1;i<=cnt[id];++i)
now=(LoveLive)now*inv[tot[p[id][i]]]%md*(tot[p[id][i]]-1)%md,--tot[p[id][i]];
}
int main(){
srand(19260817);
sieve();
cin>>n>>m;
inv[1]=1;
for(int i=2;i<=n;++i)inv[i]=(md-md/i)*1LL*inv[md%i]%md;
for(int i=1;i<=n;++i){
cin>>a[i];
memcpy(sum[i],sum[i-1],sizeof*sum);
for(int j=1;j<=cct&&pri[j]*pri[j]<=a[i];++j)
while(!(a[i]%pri[j])){
++sum[i][j];
a[i]/=pri[j];
}
if(a[i]>1){
if(a[i]<=pri[cct]){
++sum[i][num[a[i]]];
continue;
}
tj.clear();
find(a[i],23333);
for(int it:tj)
p[i][++cnt[i]]=it,lr.push_back(it);
}
}
sort(lr.begin(),lr.end());
lr.erase(unique(lr.begin(),lr.end()),lr.end());
for(int i=1;i<=n;++i)
for(int j=1;j<=cnt[i];++j)p[i][j]=lower_bound(lr.begin(),lr.end(),p[i][j])-lr.begin();
for(int i=1;i<=m;++i)cin>>q[q[i].id=i].l>>q[i].r;
sort(q+1,q+m+1);
for(int i=0;i<n<<1;++i)tot[i]=1;
for(int i=1,l=1,r=0;i<=m;++i){
while(r<q[i].r)add(++r);
while(l>q[i].l)add(--l);
while(r>q[i].r)del(r--);
while(l<q[i].l)del(l++);
int&out=ans[q[i].id];out=now;
for(int j=1;j<=cct;++j)
out=(LoveLive)out*(sum[r][j]-sum[l-1][j]+1)%md;
}
for(int i=1;i<=m;++i)
cout<<ans[i]<<'\n';
return 0;
}
[Ynoi2015]此时此刻的光辉的更多相关文章
- 【题解】Luogu P5071 [Ynoi2015]此时此刻的光辉
众所周知lxl是个毒瘤,Ynoi道道都是神仙题,题面好评 原题传送门 一看这题没有修改操作就知道这是莫队题(我也只会莫队) 我博客里对莫队的简单介绍 一个数N可以分解成\(p_1^{c_1}p_2^{ ...
- [Ynoi2015]此时此刻的光辉(莫队)
一道神题...自己写出来以后被卡常了...荣获洛谷最差解... 思路还是比较好想,对于每个数 \(\sqrt{n}\) 分块,对于 \(\sqrt{n}\) 以内的数,我们可以直接求出来.对于 \(\ ...
- P5071 [Ynoi2015]此时此刻的光辉
传送门 lxl大毒瘤 首先一个数的因子个数就是这个数的每个质因子的次数+1的积,然后考虑把每个数分解质因子,用莫队维护,然后我交上去就0分了 如果是上面那样的话,我们每一次移动指针的时间复杂度是O(这 ...
- Luogu5071 [Ynoi2015]此时此刻的光辉 【莫队】
题目链接:洛谷 这个跟上上个Ynoi题目是一样的套路,首先我们知道\(n=\prod p_i^{\alpha_i}\)时\(d(n)=\prod (\alpha_i+1)\). 首先对所有数分解质因数 ...
- 洛谷 P5071 - [Ynoi2015] 此时此刻的光辉(莫队)
洛谷题面传送门 一道其实算得上常规的题,写这篇题解是为了总结一些数论中轻微(?)优化复杂度的技巧. 首先感性理解可以发现该问题强于区间数颜色问题,无法用常用的 log 数据结构维护,因此考虑分块/莫队 ...
- 洛谷P5071 此时此刻的光辉
2s512M. 解:先分解质因数.考虑按照质因数大小是否大于√分类. 大于的就是一个数颜色个数,莫队即可n√m. 小于的直接枚举质因数做前缀和然后O(1)查询.总时间复杂度n(√m + σ(√V)). ...
- 【题解】Luogu P5313 僕たちはひとつの光([Ynoi2012]D2T2)
原题传送门 lovelive好评 比赛时只拿到了60pts,还是自己太菜了 这题的思想实际有点像Luogu P3674 小清新人渣的本愿与Luogu P5071 [Ynoi2015]此时此刻的光辉 这 ...
- [Ynoi2015]即便看不到未来
题目大意: 给定一个序列,每次询问,给出一个区间$[l,r]$. 设将区间内的元素去重后重排的数组为$p$,求$p$中长度为$1\sim 10$的极长值域连续段个数. 长度为$L$的极长值域连续段的定 ...
- [Ynoi2015]纵使日薄西山
题目大意: 给定一个序列,每次单点修改,然后进行询问. 定义一次操作为,选择一个位置$x$,将这个位置的数和左边.右边两个位置的数(不存在则忽略)各减去1,然后和0取max. 对序列中最大的位置进行一 ...
随机推荐
- 猫猫学iOS之UILabel设置圆角不成功所做调控更改
原创文章.欢迎转载.转载请注明:翟乃玉的博客 地址:http://blog.csdn.net/u013357243 如图问题 如图是我要做的效果 然而当我写好代码后,设置号label的layer圆角后 ...
- 【2014秋季版】【辛星php】【0】清晰的认识一下PHP语言
*********************PHP情结***************** 1.假设您和我经历非常相似,也可能会有这种PHP情结,为什么呢.由于我最先学习的是Java.然后学习了C++,开 ...
- Android学习笔记之:android更新ui的几种经常用法
Android主线程不能运行耗时操作.我们通常是在子线程中运行耗时操作, 我们在运行完耗时操作后,我们一般能够通过下面几种方式来实现ui界面的更新. 首先是布局文件: <LinearLayout ...
- qml
用qt非常久了.可是一直没有注意到一个叫做qml的东西.今天google了一下,总结一下我的理解. 从表面上看qml就是用css javascript那一套来做软件的GUI,和原来的C++的widge ...
- HTML5开发移动web应用——SAP UI5篇(7)
SAPUI5中支持利用Component对组件进行封装.想封装一个组件,Component的基本代码例如以下: sap.ui.define([ "sap/ui/core/UIComponen ...
- HashMap源代码剖析
大部分思路都是一样的 .仅仅是一些细节不一样.源代码中都标了出来.jdk容器源代码还是挺简单的. public class HashMap<K,V> extends AbstractMap ...
- 10.3arcmap矢量数据制作步骤
注意:在制作之前需要点将图放到原本大小.并且保存一下不然容易造成数据丢失. 在数据制作之前需要新建一个页面,用来放需要处理的原始数据 勾选ArcMap中Customize——ArcMap Option ...
- java的征途
前段时间应因缘梳理了下自己的 Java 知识体系, 成文一篇望能帮到即将走进或正在 Java 世界跋涉的程序员们. 第一张,基础图 大 约在 2003 年我开始知道 Java 的(当时还在用 Delp ...
- [NOIP 2014] 寻找道路
[题目链接] http://uoj.ac/problem/19 [算法] 首先,在反向图上从终点广搜,求出每个点是否可以在答案路径中 然后在正向图中求出源点至终点的最短路,同样可以使用广搜 时间复杂度 ...
- B1045 糖果传递 数学
糖果传递,一开始就想到了n^2的模拟贪心算法,但是一看,数据范围太大,好像只有O(N)能过...没啥方法,只好看题解,之后发现,woc,还有这种操作? 这个题直接可以用数学证明... 证明如下: 首先 ...