【BZOJ4026】dC Loves Number Theory 分解质因数+主席树
【BZOJ4026】dC Loves Number Theory
Description
Input
第一行,两个正整数,N,Q,表示序列的长度和询问的个数。
Output
Q行,对于每个询问输出一个整数。
Sample Input
3 7 10 10 5
3 4
42 44
241 242
14 9
1201 1201
0 6
245 245
7 7
6 1
1203 1203
Sample Output
240
12
1200
2
240
4
4
1200
4
题解:前置技能:强制在线版HH的项链。(好吧这道题不存在的~)
用主席树实现强制在线求区间中不同数的个数,具体做法跟树状数组的做法差不多。比如当位置i的数是x,x上一个出现的位置是j,那么我们就在i的主席树中的位置j减去1(j本身的主席树不动!!!)。当我们查询区间[l,r]中,在r的主席树中进行区间查询,这样,如果r==i并且l>j,那么我们只计算了i的贡献;如果r==i并且l<=j,那么我们依旧没有计算j的贡献;如果r<i并且l<j,那么在i之前的主席树中并没有将j删去,我们还能正常计算j的贡献。(需要好好理解一下。)
然后就水了嘛!我们知道如果$n=\prod p_i^{e_i}(p是质数)$,那么$\varphi( n)=n\prod {p_i-1\over p_i}$,所以我们只需要先预处理出所有质数,然后将每个数分解质因数,维护区间中每个质数出现的次数就好了。具体做法是:当我们分解第i个位置上的数时,如果i包含e个质因子p,那么我们要找到p上一个出现的位置j,在i的主席树中将位置j乘上$p\over p-1$(因为j处之前肯定乘过p-1),然后在i的位置乘上$(p-1)*p^{e-1}$就行了。
需要用快速幂求逆元。
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
typedef long long ll;
const int maxn=50010;
const ll mod=1000777;
int n,m,nm,num,ans,tot;
int pri[100010],last[100010],np[1000010],v[maxn],rt[maxn];
struct sag
{
int ls,rs;
ll sc;
}s[maxn*160];
ll pm(ll x,ll y)
{
ll z=1;
while(y)
{
if(y&1) z=z*x%mod;
x=x*x%mod,y>>=1;
}
return z;
}
int rd()
{
int ret=0,f=1; char gc=getchar();
while(gc<'0'||gc>'9') {if(gc=='-')f=-f; gc=getchar();}
while(gc>='0'&&gc<='9') ret=ret*10+gc-'0',gc=getchar();
return ret*f;
}
void insert(int x,int &y,int l,int r,int pos,int val)
{
if(l>r) return ;
if(!y||y==x) y=++tot,s[y].sc=s[x].sc*val%mod;
else s[y].sc=s[y].sc*val%mod;
if(l==r) return ;
int mid=l+r>>1;
if(pos<=mid) s[y].rs=(s[y].rs)?s[y].rs:s[x].rs,insert(s[x].ls,s[y].ls,l,mid,pos,val);
else s[y].ls=(s[y].ls)?s[y].ls:s[x].ls,insert(s[x].rs,s[y].rs,mid+1,r,pos,val);
}
ll query(int x,int l,int r,int a,int b)
{
if(a<=l&&r<=b) return s[x].sc;
int mid=l+r>>1;
if(b<=mid) return query(s[x].ls,l,mid,a,b);
if(a>mid) return query(s[x].rs,mid+1,r,a,b);
return query(s[x].ls,l,mid,a,b)*query(s[x].rs,mid+1,r,a,b)%mod;
}
int main()
{
n=rd(),m=rd();
int i,j,a,b;
for(i=1;i<=n;i++) v[i]=rd(),nm=max(nm,v[i]);
for(i=2;i<=nm;i++)
{
if(!np[i]) np[i]=++num,pri[num]=i;
for(j=1;j<=num&&i*pri[j]<=nm;j++)
{
np[i*pri[j]]=-1;
if(i%pri[j]==0) break;
}
}
s[0].sc=1;
for(i=1;i<=n;i++)
{
if(v[i]==1)
{
insert(rt[i-1],rt[i],1,n,i,1);
continue;
}
for(j=1;j<=num&&pri[j]*pri[j]<=v[i];j++)
{
if(v[i]%pri[j]==0)
{
v[i]/=pri[j],insert(rt[i-1],rt[i],1,n,i,pri[j]-1);
while(v[i]%pri[j]==0) v[i]/=pri[j],insert(rt[i-1],rt[i],1,n,i,pri[j]);
if(last[j]) insert(rt[i-1],rt[i],1,n,last[j],pm(pri[j]-1,mod-2)*pri[j]%mod);
last[j]=i;
}
}
if(v[i]>1)
{
j=np[v[i]];
if(last[j]) insert(rt[i-1],rt[i],1,n,last[j],pm(pri[j]-1,mod-2)*pri[j]%mod);
last[j]=i,insert(rt[i-1],rt[i],1,n,i,pri[j]-1);
}
}
for(i=1;i<=m;i++)
{
a=rd()^ans,b=rd()^ans;
ans=int(query(rt[b],1,n,a,b));
printf("%d\n",ans);
}
return 0;
}
【BZOJ4026】dC Loves Number Theory 分解质因数+主席树的更多相关文章
- 【bzoj4026】dC Loves Number Theory 可持久化线段树
题目描述 dC 在秒了BZOJ 上所有的数论题后,感觉萌萌哒,想出了这么一道水题,来拯救日益枯竭的水题资源. 给定一个长度为 n的正整数序列A,有q次询问,每次询问一段区间内所有元素乘积的φ(φ(n ...
- [BZOJ4026]dC Loves Number Theory(线段树)
根据欧拉函数的定义式可知,可以先算出a[l]*a[l+1]*...*a[r]的值,然后枚举所有存在的质因子*(p-1)/p. 发现这里区间中一个质因子只要计算一次,所以指计算“上一个同色点在区间外”的 ...
- BZOJ4026: dC Loves Number Theory
Description dC 在秒了BZOJ 上所有的数论题后,感觉萌萌哒,想出了这么一道水题,来拯救日益枯 竭的水题资源. 给定一个长度为 n的正整数序列A,有q次询问,每次询问一段区间内所 ...
- [BZOJ4026]dC Loves Number Theory 欧拉函数+线段树
链接 题意:给定长度为 \(n\) 的序列 A,每次求区间 \([l,r]\) 的乘积的欧拉函数 题解 考虑离线怎么搞,将询问按右端点排序,然后按顺序扫这个序列 对于每个 \(A_i\) ,枚举它的质 ...
- BZOJ 4026: dC Loves Number Theory 可持久化线段树 + 欧拉函数 + 数学
Code: #include <bits/stdc++.h> #define ll long long #define maxn 50207 #define setIO(s) freope ...
- [bzoj4026]dC Loves Number Theory_主席树_质因数分解_欧拉函数
dC Loves Number Theory 题目大意:dC 在秒了BZOJ 上所有的数论题后,感觉萌萌哒,想出了这么一道水题,来拯救日益枯竭的水题资源. 给定一个长度为 n的正整数序列A,有q次询问 ...
- bzoj 4026 dC Loves Number Theory 主席树+欧拉函数
题目描述 dC 在秒了BZOJ 上所有的数论题后,感觉萌萌哒,想出了这么一道水题,来拯救日益枯竭的水题资源.给定一个长度为 n的正整数序列A,有q次询问,每次询问一段区间内所有元素乘积的φ(φ(n)代 ...
- BZOJ 4026 dC Loves Number Theory (主席树+数论+欧拉函数)
题目大意:给你一个序列,求出指定区间的(l<=i<=r) mod 1000777 的值 还复习了欧拉函数以及线性筛逆元 考虑欧拉函数的的性质,(l<=i<=r),等价于 (p[ ...
- bzoj 4026 dC Loves Number Theory
把我写吐了 太弱了 首先按照欧拉函数性质 我只需要统计区间不同质数个数就好了 一眼主席树 其次我被卡了分解质因数这里 可以通过质数筛时就建边解决 不够灵性啊,不知道如何改 #include<bi ...
随机推荐
- elasticsearch 基础性操作
1 基础概念 Elasticsearch是一个近实时的系统,从你写入数据到数据可以被检索到,一般会有1秒钟的延时.Elasticsearch是基于Lucene的,Lucene的读写是两个分开的句柄,往 ...
- 怎样优雅的研究 RGSS3 (四) 使窗体从画面边缘弹出
在非常多游戏中,窗体能够从游戏画面的边缘弹出. 而在 RGSS3 的默认脚本中时没有这样的功能的,当在地图上按下取消键时.游戏菜单会突然出现. 如今我们能够为主菜单加入动画效果,使其在屏幕边缘弹出. ...
- Centos 6安装 Jenkins
前言 持续集成的概念 持续集成,Continuous integration ,简称CI. 持续集成正是针对这一类问题的一种软件开发实践.它倡导团队开发成员必须经常集成他们的工作,甚至每天都可能发生多 ...
- block传值以及利用block封装一个网络请求类
1.block在俩个UIViewController间传值 近期刚学了几招block 的高级使用方法,事实上就是利用block语法在俩个UIViewController之间传值,在这里分享给刚開始学习 ...
- m 调用传参图片切换
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- python ——单下划线(约定)
命名规则: 通常使用小写单词,必要时用下划线分隔增加可读性. 使用一个前导下划线仅用于不打算作为类的公共接口的内部方法和实例变量. Python不强制要求这样; 它取决于程序员是否遵守这个约定. 使用 ...
- 数据库设计--数据流图(DFD)
1.数据流图的定义 数据流图(DFD)是结构化分析方法中使用的工具,它以图形的方式描绘数据在系统中流动和处理的过程, 因为它仅仅反映系统必须完毕的逻辑功能.所以它是一种功能模型. 在结构化开发方法中. ...
- APP开发关于缓存
1 http://www.cnblogs.com/qianxudetianxia/archive/2012/02/20/2112128.html 1.1 http://blog.csdn.net/ln ...
- .net core 2.0小白笔记(一):开发运行环境搭建
小白一枚,有任何不妥之处敬请指教 这里不讨论什么设计模式,什么架构,什么什么,就是入门,简单的入门,虽然能跨平台,但是这里还是在win的环境下进行,不扯的那么远 其实官网文档写的挺不错的了,就是偶尔有 ...
- requests ssl 报错
使用requests下载日志出现HTTPSConnectionPool(host='***', port=443): Max retries exceeded with url: ******(Cau ...