传送门

lxl大毒瘤

首先一个数的因子个数就是这个数的每个质因子的次数+1的积,然后考虑把每个数分解质因子,用莫队维护,然后我交上去就0分了

如果是上面那样的话,我们每一次移动指针的时间复杂度是O(这个数的质因子个数),再加上我人傻常数大,T很正常……

于是按照memset0的说法,可以预处理质因子的前缀和,简单来说就是对于小于\(\sqrt{mx}\)的所有质因子维护前缀和,直接统计,大于的暴力在莫队的时候更新。因为每个数大于\(\sqrt{mx}\)的质因子个数为\(O(1)\),所以暴力更新的复杂度是\(O(1)\)的

然后我维护前缀和这里想岔了……死活没想明白怎么用前缀和更新答案……实际上就是用前缀和每一次暴力统计所有小于\(\sqrt{mx}\)的质因子个数,总共统计次数为\(O(q)\),所以这一部分的时间复杂度为\(O(q\sqrt{mx})\)

然后加起来差不多是\(O(n\sqrt{n})\)

//minamoto
#include<bits/stdc++.h>
#define R register
#define IT vector<node>::iterator
#define fp(i,a,b) for(R int i=a,I=b+1;i<I;++i)
#define fd(i,a,b) for(R int i=a,I=b-1;i>I;--i)
#define go(u) for(IT it=v[u].begin();it!=v[u].end();++it)
template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;}
using namespace std;
char buf[1<<21],*p1=buf,*p2=buf;
inline char getc(){return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;}
int read(){
R int res,f=1;R char ch;
while((ch=getc())>'9'||ch<'0')(ch=='-')&&(f=-1);
for(res=ch-'0';(ch=getc())>='0'&&ch<='9';res=res*10+ch-'0');
return res*f;
}
char sr[1<<21],z[20];int C=-1,Z=0;
inline void Ot(){fwrite(sr,1,C+1,stdout),C=-1;}
void print(R int x){
if(C>1<<20)Ot();if(x<0)sr[++C]='-',x=-x;
while(z[++Z]=x%10+48,x/=10);
while(sr[++C]=z[Z],--Z);sr[++C]='\n';
}
const int N=1e5+5,P=19260817;
struct node{
int v,cnt;
node(){}
node(R int v,R int cnt):v(v),cnt(cnt){}
};vector<node>v[N];map<int,int>mp;map<int,int>::iterator it;
int p[N],inv[P+5],cnt[N<<1],b[N],ans[N],rt[N],vis[N],sum[N][165],a[N];
int m,lim,n,now=1,S,Q,cc,L=155,mx,l,r;
struct query{
int l,r,id;
inline bool operator <(const query &b)const{return rt[l]==rt[b.l]?rt[l]&1?r<b.r:r>b.r:l<b.l;}
}q[N];
void init(int n){
fp(i,2,n){
if(!vis[i])p[++m]=i,mp[i]=m;
for(R int j=1;j<=m&&i*p[j]<=n;++j){
vis[i*p[j]]=1;
if(i%p[j]==0)break;
}
}
}
inline void ins(R int x,R int i,R int j){i<=L?(sum[x][i]+=j,0):(v[x].push_back(node(i,j)),0);}
void solve(int x,int id){
for(int i=1;i<=lim&&1ll*p[i]*p[i]<=x;++i)if(x%p[i]==0){
cc=0;while(x%p[i]==0)x/=p[i],++cc;
ins(id,i,cc);
}if(x!=1){
it=mp.find(x);
if(it==mp.end())p[++m]=x,mp[x]=m,x=m;
else x=it->second;
ins(id,x,1);
}
}
void add(int id){
go(id)now=1ll*now*inv[cnt[it->v]+1]%P,cnt[it->v]+=it->cnt,now=1ll*now*(cnt[it->v]+1)%P;
}
void del(int id){
go(id)now=1ll*now*inv[cnt[it->v]+1]%P,cnt[it->v]-=it->cnt,now=1ll*now*(cnt[it->v]+1)%P;
}
int main(){
// freopen("testdata.in","r",stdin);
// freopen("testdata.out","w",stdout);
n=read(),Q=read(),S=sqrt(n);fp(i,1,n)a[i]=read(),cmax(mx,a[i]),rt[i]=(i-1)/S;init(sqrt(mx));
lim=m;fp(i,1,n){
fp(j,1,L)sum[i][j]=sum[i-1][j];solve(a[i],i);
}inv[0]=inv[1]=1;fp(i,2,P-1)inv[i]=1ll*(P-P/i)*inv[P%i]%P;
fp(i,1,Q)q[i].l=read(),q[i].r=read(),q[i].id=i;
sort(q+1,q+1+Q);l=1,r=0;
fp(i,1,Q){
while(l>q[i].l)add(--l);while(r<q[i].r)add(++r);
while(l<q[i].l)del(l++);while(r>q[i].r)del(r--);
ans[q[i].id]=now;fp(j,1,L)ans[q[i].id]=1ll*ans[q[i].id]*(sum[r][j]-sum[l-1][j]+1)%P;
}fp(i,1,Q)print(ans[i]);return Ot(),0;
}

P5071 [Ynoi2015]此时此刻的光辉的更多相关文章

  1. 【题解】Luogu P5071 [Ynoi2015]此时此刻的光辉

    众所周知lxl是个毒瘤,Ynoi道道都是神仙题,题面好评 原题传送门 一看这题没有修改操作就知道这是莫队题(我也只会莫队) 我博客里对莫队的简单介绍 一个数N可以分解成\(p_1^{c_1}p_2^{ ...

  2. 洛谷 P5071 - [Ynoi2015] 此时此刻的光辉(莫队)

    洛谷题面传送门 一道其实算得上常规的题,写这篇题解是为了总结一些数论中轻微(?)优化复杂度的技巧. 首先感性理解可以发现该问题强于区间数颜色问题,无法用常用的 log 数据结构维护,因此考虑分块/莫队 ...

  3. [Ynoi2015]此时此刻的光辉

    题目大意: 给定一个序列,每次询问一段区间的数的乘积的约数个数. 解题思路: 在太阳西斜的这个世界里,置身天上之森.等这场战争结束之后,不归之人与望眼欲穿的众人, 人人本着正义之名,长存不灭的过去.逐 ...

  4. [Ynoi2015]此时此刻的光辉(莫队)

    一道神题...自己写出来以后被卡常了...荣获洛谷最差解... 思路还是比较好想,对于每个数 \(\sqrt{n}\) 分块,对于 \(\sqrt{n}\) 以内的数,我们可以直接求出来.对于 \(\ ...

  5. Luogu5071 [Ynoi2015]此时此刻的光辉 【莫队】

    题目链接:洛谷 这个跟上上个Ynoi题目是一样的套路,首先我们知道\(n=\prod p_i^{\alpha_i}\)时\(d(n)=\prod (\alpha_i+1)\). 首先对所有数分解质因数 ...

  6. 洛谷P5071 此时此刻的光辉

    2s512M. 解:先分解质因数.考虑按照质因数大小是否大于√分类. 大于的就是一个数颜色个数,莫队即可n√m. 小于的直接枚举质因数做前缀和然后O(1)查询.总时间复杂度n(√m + σ(√V)). ...

  7. 【题解】Luogu P5313 僕たちはひとつの光([Ynoi2012]D2T2)

    原题传送门 lovelive好评 比赛时只拿到了60pts,还是自己太菜了 这题的思想实际有点像Luogu P3674 小清新人渣的本愿与Luogu P5071 [Ynoi2015]此时此刻的光辉 这 ...

  8. [Ynoi2015]即便看不到未来

    题目大意: 给定一个序列,每次询问,给出一个区间$[l,r]$. 设将区间内的元素去重后重排的数组为$p$,求$p$中长度为$1\sim 10$的极长值域连续段个数. 长度为$L$的极长值域连续段的定 ...

  9. [Ynoi2015]纵使日薄西山

    题目大意: 给定一个序列,每次单点修改,然后进行询问. 定义一次操作为,选择一个位置$x$,将这个位置的数和左边.右边两个位置的数(不存在则忽略)各减去1,然后和0取max. 对序列中最大的位置进行一 ...

随机推荐

  1. POJ 3281 [网络流dinic算法模板]

    题意: 农场主有f种食物,d种饮料,n头牛. 接下来的n行每行第一个数代表第i头牛喜欢吃的食物数量,和第i头牛喜欢喝的饮料数目. 接下来分别是喜欢的食物和饮料的编号. 求解:农场主最多能保证几头牛同时 ...

  2. flash update

    https://get.adobe.com/cn/flashplayer/otherversions/

  3. eclipse导入maven工程步骤

    转自:http://jingyan.baidu.com/article/cbf0e500a6e3252eaa2893c1.html 感谢作者 步骤一 : 选择 “Import”操作 有两个途径可以选择 ...

  4. 拷贝地图 CopyAndOverwriteMap()

    private void CopyAndOverwriteMap() { //Get IObjectCopy interface IObjectCopy objectCopy = new Object ...

  5. Cg入门6:函数2

    内建函数分为四类: 1.数学函数 2.几何函数 3.纹理函数 4.导数函数:事实上就是片段函数

  6. 247. Segment Tree Query II

    最后更新 二刷 09-Jna-2017 利用线段树进行区间查找,重点还是如何判断每一层的覆盖区间,和覆盖去见与当前NODE值域的关系. public class Solution { public i ...

  7. [Javascript] Link to Other Objects through the JavaScript Prototype Chain

    Objects have the ability to use data and methods that other objects contain, as long as it lives on ...

  8. Java静态分派与动态分派(二)

    方法调用并不等于方法执行,方法调用阶段唯一的任务就是确定被调用方法的版本(即调用哪一个方法),暂时还不涉及方法内部的具体运行过程. 在程序运行时,进行方法调用是最普遍.最频繁的操作,但是Class文件 ...

  9. MVC在View中页面跳转

    在做人事系统的时候须要用到页面跳转,那么页面跳转究竟用什么方法好呢?依照曾经的思路,我就会这么写. <span style="font-size:18px;">wind ...

  10. 程序C++ to C#交互

    第一次用C#调用C/C++生成的DLL文件,感觉有点新鲜,事实上仅仅是实现了执行在公共语言执行库 (CLR) 的控制之外的"非托管代码"(执行在公共语言执行库(CLR)的控制之中的 ...