bzoj 4026 dC Loves Number Theory 主席树+欧拉函数
题目描述
dC 在秒了BZOJ 上所有的数论题后,感觉萌萌哒,想出了这么一道水题,来拯救日益枯竭的水题资源。
给定一个长度为 n的正整数序列A,有q次询问,每次询问一段区间内所有元素乘积的φ(φ(n)代表1~n 中与n互质的数的个数) 。由于答案可能很大,所以请对答案 mod 10610^6106 + 777。 (本题强制在线,所有询问操作的l,r都需要 xor上一次询问的答案 lastans,初始时,lastans = 0)
输入格式
第一行,两个正整数,N,Q,表示序列的长度和询问的个数。
第二行有N 个正整数,第i个表示Ai.
下面Q行,每行两个正整数,l r,表示询问[l ^ lastans,r ^ lastans]内所有元素乘积的φ
输出格式
Q行,对于每个询问输出一个整数。
样例
样例输入
5 10
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
样例输出
40
240
12
1200
2
240
4
4
1200
4
数据范围与提示
1 <= N <= 50000 1 <= Q <= 100000 1 <= Ai <= 10610^6 106
这是个比较高级的的题目。。。原来一直是开权值的主席树,看到此题首先想到莫比乌斯反演,但是本题用最简单的容斥算欧拉即可。也就是说每个点都有相应的质因数,这些质因数不重复的相乘即为最难维护的部分,考虑主席树要存 在加入该点后每个线段树区间的phi值情况,最后用区间拼凑,要每个点都考虑是因为加入该点后之前区间的质数不再对答案做贡献,我们只算最新加入的相同质数,如果要是想只算第一次加入的话,后面的区间就没法计算贡献,而主席树可以访问历史状态,因此我们可以访问加入该节点之前的状态,所以存最新的相同质数可以达到我们的目的,那么具体操作就是,就是我们扫描整个数组,然后对它分解质因数,用一个pre数组记录某个质数最早出现的位置,如果为零,直接把这个质数的贡献((pi-1)/pi)乘入该点主席树的位置,如果不为零,考虑在现在版本上去掉该质数之前区间的贡献,即在现在点的主席树pre位置除以(pi-1)/pi,当然在此题有取模,所以我们可以用逆元,(不要怂,其实逆元代码也就一行)这题细节贼多,日了我好久。。。。注意数组多开点,因为这个主席树你改一次加条链,一个大数质因数可能特别多,然后就成RE树了。
Code:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
const int M=50020,mod=1e6+777;
int rt[M*80],lc[M*80],rc[M*80],z[2*mod+20],tt,n,m,tot;
int fac[2*mod+20],pre[2*mod+20],a[M*40],p[2*mod+20],inv[2*mod+20];
int sum[M*80];
int rd()
{
char cc=getchar();
int s=0,w=1;
while(cc<'0'||cc>'9'){if(cc=='-')w=-1;cc=getchar();}
while(cc>='0'&&cc<='9') s=(s<<3)+(s<<1)+cc-'0',cc=getchar();
return s*w;
}
void first()
{
for(int i=2;i<=mod;i++)
{
if(p[i]==0){p[i]=i;z[++tot]=i;}
for(int j=1;j<=tot;j++)
{
if(z[j]>p[i]||z[j]>(mod/i)) break;
p[i*z[j]]=z[j];
}
}
inv[1]=1;
for(int i=2;i<mod;i++)
inv[i]=(1ll*(mod-mod/i)*inv[mod%i])%mod;
}
void build(int &k,int l,int r)
{
k=++tt;
sum[k]=1;
if(l==r) return;
int mid=(l+r)>>1;
build(lc[k],l,mid);build(rc[k],mid+1,r);
}
void modify(int &x,int k,int l,int r,int ip,ll w)
{
x=++tt;
lc[x]=lc[k];rc[x]=rc[k];
sum[x]=(1ll*sum[k]*w)%mod;
if(l==r) return;
int mid=(l+r)>>1;
if(ip<=mid) modify(lc[x],lc[k],l,mid,ip,w);
else modify(rc[x],rc[k],mid+1,r,ip,w);
}
int query(int k,int l,int r,int x,int y)
{
int mid=(l+r)>>1;
if(l==x&&r==y) return sum[k];
if(y<=mid) return query(lc[k],l,mid,x,y);
else if(x>mid) return query(rc[k],mid+1,r,x,y);
return 1ll*query(lc[k],l,mid,x,mid)*query(rc[k],mid+1,r,mid+1,y)%mod;
}
void cut(int k)
{
int nn=a[k],wi=a[k],tmp1=1,tmp2=1;
while(nn!=1)
{
int y=p[nn];
while(nn%y==0) nn/=y;
if(pre[y])
{
if(rt[k]==0) modify(rt[k],rt[k-1],1,n,pre[y],(1ll*inv[y-1]*y)%mod);
else modify(rt[k],rt[k],1,n,pre[y],(1ll*inv[y-1]*y)%mod);
}
wi=((1ll*wi*(y-1)%mod)*inv[y])%mod;
pre[y]=k;
}
if(rt[k]==0) modify(rt[k],rt[k-1],1,n,k,(1ll*wi)%mod);
else modify(rt[k],rt[k],1,n,k,(1ll*wi)%mod);
}
int main()
{
first();
n=rd(),m=rd();
fac[0]=1;
build(rt[0],1,n);
for(int i=1;i<=n;i++)
{
a[i]=rd();
cut(i);
}
int last=0;
for(int i=1;i<=m;i++)
{
int l=rd()^last,r=rd()^last;
last=(1ll*query(rt[r],1,n,l,r)%mod);
printf("%d\n",last);
}
}
bzoj 4026 dC Loves Number Theory 主席树+欧拉函数的更多相关文章
- BZOJ 4026 dC Loves Number Theory (主席树+数论+欧拉函数)
题目大意:给你一个序列,求出指定区间的(l<=i<=r) mod 1000777 的值 还复习了欧拉函数以及线性筛逆元 考虑欧拉函数的的性质,(l<=i<=r),等价于 (p[ ...
- bzoj 4026 dC Loves Number Theory
把我写吐了 太弱了 首先按照欧拉函数性质 我只需要统计区间不同质数个数就好了 一眼主席树 其次我被卡了分解质因数这里 可以通过质数筛时就建边解决 不够灵性啊,不知道如何改 #include<bi ...
- BZOJ 4026: dC Loves Number Theory 可持久化线段树 + 欧拉函数 + 数学
Code: #include <bits/stdc++.h> #define ll long long #define maxn 50207 #define setIO(s) freope ...
- BZOJ_4026_dC Loves Number Theory _主席树+欧拉函数
BZOJ_4026_dC Loves Number Theory _主席树+欧拉函数 Description dC 在秒了BZOJ 上所有的数论题后,感觉萌萌哒,想出了这么一道水题,来拯救日益枯 竭 ...
- [bzoj4026]dC Loves Number Theory_主席树_质因数分解_欧拉函数
dC Loves Number Theory 题目大意:dC 在秒了BZOJ 上所有的数论题后,感觉萌萌哒,想出了这么一道水题,来拯救日益枯竭的水题资源. 给定一个长度为 n的正整数序列A,有q次询问 ...
- [BZOJ4026]dC Loves Number Theory(线段树)
根据欧拉函数的定义式可知,可以先算出a[l]*a[l+1]*...*a[r]的值,然后枚举所有存在的质因子*(p-1)/p. 发现这里区间中一个质因子只要计算一次,所以指计算“上一个同色点在区间外”的 ...
- 【BZOJ4026】dC Loves Number Theory 分解质因数+主席树
[BZOJ4026]dC Loves Number Theory Description dC 在秒了BZOJ 上所有的数论题后,感觉萌萌哒,想出了这么一道水题,来拯救日益枯竭的水题资源. 给 ...
- 【bzoj4026】dC Loves Number Theory 可持久化线段树
题目描述 dC 在秒了BZOJ 上所有的数论题后,感觉萌萌哒,想出了这么一道水题,来拯救日益枯竭的水题资源. 给定一个长度为 n的正整数序列A,有q次询问,每次询问一段区间内所有元素乘积的φ(φ(n ...
- [BZOJ4026]dC Loves Number Theory 欧拉函数+线段树
链接 题意:给定长度为 \(n\) 的序列 A,每次求区间 \([l,r]\) 的乘积的欧拉函数 题解 考虑离线怎么搞,将询问按右端点排序,然后按顺序扫这个序列 对于每个 \(A_i\) ,枚举它的质 ...
随机推荐
- 【bzoj1269】[AHOI2006]文本编辑器editor
在bzoj上乱翻,发现了可持久化并查集,然后baidu了一下,发现一种叫rope的东西. !!!真的太爽了!!! 直接上代码,感受一下(也是蒯来的). 由于rope的底层实现,in ...
- Bootstrap 过渡效果 transition.js源码分析
前言: 阅读建议:去github下载一个完整dom然后把,本篇代码复制进去然后运行就好了以地址 Bootstrap 自带的 JavaScript 插件的动画效果几乎都是使用 CSS 过渡实现的,那么判 ...
- Spring 的Bean管理的常用注解
属性注入的注解(使用注解注入的方式,可以不用提供set方法) @Value 用于注入普通类型 @Autowired 自动装配 :默认按类型进行装配 按名称注入 @Qualifier 强制使用名称注入 ...
- VC/MFC列表CListCtrl类的LVCOLUMN和LVITEM详解
列表视图控件(List Control)列表视图控件是一种非常常用的控件,在需要以报表形式显示数据时,列表控件通常是最好的选择,许多专用的数据报表控件,也是在它的基础上派生而来.与树视图类似,列表 ...
- 2014年国内最热门的.NET开源项目TOP25
编者按:在2014年初时,微软宣布成立.NET基金会,全面支持开源项目.如今将过一年的时间,目前国内的开源项目到底如何了?下面我们就来细数一下国内25款比较优秀的.NET开源项目. 作者:acdoma ...
- poj 3621(最优比率环)
Sightseeing Cows Farmer John has decided to reward his cows for their hard work by taking them on a ...
- 让你彻底明白JAVA中堆与栈的区别
原文地址:http://www.2cto.com/kf/201302/190704.html 简单的说: Java把内存划分成两种:一种是栈内存,一种是堆内存. 在函数中定义的一些基本类型的变量和对象 ...
- bzoj 1671: [Usaco2005 Dec]Knights of Ni 骑士【bfs】
bfs预处理出每个点s和t的距离d1和d2(无法到达标为inf),然后在若干灌木丛格子(x,y)里取min(d1[x][y]+d2[x][y]) /* 0:贝茜可以通过的空地 1:由于各种原因而不可通 ...
- [SDOI2011]消防(单调队列,树的直径,双指针)
消防 2011年 时间限制: 2 s 空间限制: 256000 KB 题目等级 : 大师 Master 题目描述 Description 某个国家有n个城市,这n个城市中任意两个都连通且有 ...
- hexo简易脚本
!/bin/bash 检查是否为master分支.目录是否正确 function git-branch-name { git symbolic-ref --short -q HEAD } functi ...