P5071 [Ynoi2015]此时此刻的光辉
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]此时此刻的光辉的更多相关文章
- 【题解】Luogu P5071 [Ynoi2015]此时此刻的光辉
众所周知lxl是个毒瘤,Ynoi道道都是神仙题,题面好评 原题传送门 一看这题没有修改操作就知道这是莫队题(我也只会莫队) 我博客里对莫队的简单介绍 一个数N可以分解成\(p_1^{c_1}p_2^{ ...
- 洛谷 P5071 - [Ynoi2015] 此时此刻的光辉(莫队)
洛谷题面传送门 一道其实算得上常规的题,写这篇题解是为了总结一些数论中轻微(?)优化复杂度的技巧. 首先感性理解可以发现该问题强于区间数颜色问题,无法用常用的 log 数据结构维护,因此考虑分块/莫队 ...
- [Ynoi2015]此时此刻的光辉
题目大意: 给定一个序列,每次询问一段区间的数的乘积的约数个数. 解题思路: 在太阳西斜的这个世界里,置身天上之森.等这场战争结束之后,不归之人与望眼欲穿的众人, 人人本着正义之名,长存不灭的过去.逐 ...
- [Ynoi2015]此时此刻的光辉(莫队)
一道神题...自己写出来以后被卡常了...荣获洛谷最差解... 思路还是比较好想,对于每个数 \(\sqrt{n}\) 分块,对于 \(\sqrt{n}\) 以内的数,我们可以直接求出来.对于 \(\ ...
- Luogu5071 [Ynoi2015]此时此刻的光辉 【莫队】
题目链接:洛谷 这个跟上上个Ynoi题目是一样的套路,首先我们知道\(n=\prod p_i^{\alpha_i}\)时\(d(n)=\prod (\alpha_i+1)\). 首先对所有数分解质因数 ...
- 洛谷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. 对序列中最大的位置进行一 ...
随机推荐
- CSY版最大团,速度快一倍
#include <bits/stdc++.h> using namespace std; #define REP(i, n) for(int i(0); i < (n); ++i) ...
- web.py 使用 db.select 返回的数据只能遍历一次
2013-10-05 23:04:33| 1. web.py 使用 db.select 返回的数据只能遍历一次import webdb = web.database(dbn='mysql', db ...
- Edit Distance(动态规划,难)
Given two words word1 and word2, find the minimum number of steps required to convert word1 to word2 ...
- mybatis <!-- useGeneratedKeys="true"把新增加的主键赋值到自己定义的keyProperty(id)中 -->
<!-- useGeneratedKeys="true"把新增加的主键赋值到自己定义的keyProperty(id)中 -->
- java 定时备份数据库
原文:http://www.open-open.com/code/view/1447490829678 /** 操作数据库 */ public class BackupDb { public Stri ...
- md5sum使用注意事项
1. linux 命令行的 md5sum命令 echo -n "123456" | md5sum //echo的时候, 默认是自带回车的, 必须要去掉 -n 去掉回车. 2 ...
- 设计模式 之代理(Proxy)模式
为什么这里要定义代理呢?所谓代理代理,当然就是你不想做的事.找别人去做,这就是代理.所以,当你写代码的时候.你想保持类的简单性.重用性.你就能够把事件尽量都交给其他类去做.自己仅仅管做好自己的事.也就 ...
- [LeetCode][Java] Roman to Integer
题目: Given a roman numeral, convert it to an integer. Input is guaranteed to be within the range from ...
- vector draw 试用期结束的 激活方法
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Licenses\DBEA4D42-0745-428e-B17A-A5B6CA3AB34B] 把这个注冊表给删 了
- Android 封装实现各种样式对话框
先上图 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/disso ...