Description

 dC 在秒了BZOJ 上所有的数论题后,感觉萌萌哒,想出了这么一道水题,来拯救日益枯
竭的水题资源。 
  给定一个长度为 n的正整数序列A,有q次询问,每次询问一段区间内所有元素乘积的
φ(φ(n)代表1~n 中与n互质的数的个数) 。由于答案可能很大,所以请对答案 mod 10^6 + 
777。 (本题强制在线,所有询问操作的l,r都需要 xor上一次询问的答案 lastans,初始时,
lastans = 0) 

Input

第一行,两个正整数,N,Q,表示序列的长度和询问的个数。

第二行有N 个正整数,第i个表示Ai. 
下面Q行,每行两个正整数,l r,表示询问[l ^ lastans,r ^ lastans]内所有元素乘积的φ 

Output

Q行,对于每个询问输出一个整数。

Sample Input

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

Sample Output

40
240
12
1200
2
240
4
4
1200
4

HINT

1 <= N <= 50000

1 <= Q <= 100000

1 <= Ai <= 10^6 
 
 
考虑phi函数的定义
phi(n)=n*∏(pi-1)/pi。
所以我们对于每个询问,计算出询问区间内有多少不同的素数就行啦。
这难道不是一个经典问题吗?在线回答区间不同数的个数。
设f[i]表示第i个素数上一次出现的位置,那么我们用函数式线段树计算一下区间内f[i]<L-1的数的(pi-1)/pi之积即可。
一个正整数最多有logn个质因子,而每插入一个质因子是logn的,所以时间复杂度为O(nlog^2n)-O(logn)。
另外掌握了O(n)求1到n逆元的姿势。
#include<cstdio>
#include<cctype>
#include<queue>
#include<cmath>
#include<cstring>
#include<algorithm>
#define rep(i,s,t) for(int i=s;i<=t;i++)
#define dwn(i,s,t) for(int i=s;i>=t;i--)
#define ren for(int i=first[x];i;i=next[i])
using namespace std;
const int BufferSize=<<;
char buffer[BufferSize],*head,*tail;
inline char Getchar() {
if(head==tail) {
int l=fread(buffer,,BufferSize,stdin);
tail=(head=buffer)+l;
}
return *head++;
}
inline int read() {
int x=,f=;char c=Getchar();
for(;!isdigit(c);c=Getchar()) if(c=='-') f=-;
for(;isdigit(c);c=Getchar()) x=x*+c-'';
return x*f;
}
typedef long long ll;
const int maxn=;
const int mod=;
const int maxnode=;
int n,m,cnt,A[maxn],vis[mod+],first[mod+],pri[mod],next[mod*],to[mod*],e;
ll inv[mod+],S[maxn],sumv[maxnode],lastans;
void init() {
inv[]=inv[]=;
rep(i,,mod) inv[i]=((mod-mod/i)*inv[mod%i]+mod)%mod;
rep(i,,) if(!vis[i]) {
pri[++cnt]=i;
for(int j=i;j<=;j+=i) {
vis[j]=;
to[++e]=cnt;next[e]=first[j];first[j]=e;
}
}
}
int root[maxn],last[mod+],ls[maxnode],rs[maxnode],ToT;
void update(int& y,int x,int l,int r,int p,ll v) {
sumv[y=++ToT]=((x?sumv[x]:)*v)%mod;if(l==r) return;
int mid=l+r>>;ls[y]=ls[x];rs[y]=rs[x];
if(p<=mid) update(ls[y],ls[x],l,mid,p,v);
else update(rs[y],rs[x],mid+,r,p,v);
}
ll query(int y,int l,int r,int pos) {
if(l==r) return y?sumv[y]:;
int mid=l+r>>;
if(pos<=mid) return query(ls[y],l,mid,pos);
return ((ls[y]?sumv[ls[y]]:)*query(rs[y],mid+,r,pos))%mod;
}
int main() {
init();S[]=;
n=read();m=read();
rep(i,,n) A[i]=read(),S[i]=(S[i-]*A[i])%mod;
rep(x,,n) {
root[x]=root[x-];
for(int i=first[A[x]];i;i=next[i]) update(root[x],root[x],,n,last[to[i]],(pri[to[i]]-)*inv[pri[to[i]]]%mod),last[to[i]]=x;
}
while(m--) {
int l=read()^lastans,r=read()^lastans;
lastans=(S[r]*inv[S[l-]])%mod;
(lastans*=inv[query(root[l-],,n,l-)]*query(root[r],,n,l-))%=mod;
printf("%lld\n",lastans);
}
return ;
}

BZOJ4026: dC Loves Number Theory的更多相关文章

  1. [BZOJ4026]dC Loves Number Theory(线段树)

    根据欧拉函数的定义式可知,可以先算出a[l]*a[l+1]*...*a[r]的值,然后枚举所有存在的质因子*(p-1)/p. 发现这里区间中一个质因子只要计算一次,所以指计算“上一个同色点在区间外”的 ...

  2. [BZOJ4026]dC Loves Number Theory 欧拉函数+线段树

    链接 题意:给定长度为 \(n\) 的序列 A,每次求区间 \([l,r]\) 的乘积的欧拉函数 题解 考虑离线怎么搞,将询问按右端点排序,然后按顺序扫这个序列 对于每个 \(A_i\) ,枚举它的质 ...

  3. 【BZOJ4026】dC Loves Number Theory 分解质因数+主席树

    [BZOJ4026]dC Loves Number Theory Description  dC 在秒了BZOJ 上所有的数论题后,感觉萌萌哒,想出了这么一道水题,来拯救日益枯竭的水题资源.    给 ...

  4. [bzoj4026]dC Loves Number Theory_主席树_质因数分解_欧拉函数

    dC Loves Number Theory 题目大意:dC 在秒了BZOJ 上所有的数论题后,感觉萌萌哒,想出了这么一道水题,来拯救日益枯竭的水题资源. 给定一个长度为 n的正整数序列A,有q次询问 ...

  5. 【bzoj4026】dC Loves Number Theory 可持久化线段树

    题目描述 dC 在秒了BZOJ 上所有的数论题后,感觉萌萌哒,想出了这么一道水题,来拯救日益枯竭的水题资源.  给定一个长度为 n的正整数序列A,有q次询问,每次询问一段区间内所有元素乘积的φ(φ(n ...

  6. bzoj 4026 dC Loves Number Theory 主席树+欧拉函数

    题目描述 dC 在秒了BZOJ 上所有的数论题后,感觉萌萌哒,想出了这么一道水题,来拯救日益枯竭的水题资源.给定一个长度为 n的正整数序列A,有q次询问,每次询问一段区间内所有元素乘积的φ(φ(n)代 ...

  7. bzoj 4026 dC Loves Number Theory

    把我写吐了 太弱了 首先按照欧拉函数性质 我只需要统计区间不同质数个数就好了 一眼主席树 其次我被卡了分解质因数这里 可以通过质数筛时就建边解决 不够灵性啊,不知道如何改 #include<bi ...

  8. BZOJ 4026 dC Loves Number Theory (主席树+数论+欧拉函数)

    题目大意:给你一个序列,求出指定区间的(l<=i<=r) mod 1000777 的值 还复习了欧拉函数以及线性筛逆元 考虑欧拉函数的的性质,(l<=i<=r),等价于 (p[ ...

  9. BZOJ 4026: dC Loves Number Theory 可持久化线段树 + 欧拉函数 + 数学

    Code: #include <bits/stdc++.h> #define ll long long #define maxn 50207 #define setIO(s) freope ...

随机推荐

  1. 【OpenStack】OpenStack系列13之Nova源码解析与API扩展

    学习思路 议程:代码结构-主干流程-分层架构-业务模型-数据库模型-消息模型 分布式架构:Api:横向扩展    rpc:纵向扩展 分层架构:Controller接口层.View/Manager逻辑层 ...

  2. 【转】Oracle数据库中Sequence的用法

    在Oracle数据库中,sequence等同于序列号,每次取的时候sequence会自动增加,一般会作用于需要按序列号排序的地方. 1.Create Sequence (注释:你需要有CREATE S ...

  3. cocos2d-x的Android工程开启c++0x特性

    首先一定要确定你所安装NDK支持c++0x(我安装的android-ndk-r8) 文本打开 项目目录/proj.android/jni/Application.mk 在APP_CPPFLAGS那一行 ...

  4. MFC 文件按行读写 CStdioFile

    //写文件 CStdioFile file; file.Open("test.txt",CFile::modeCreate|CFile::modeReadWrite); file. ...

  5. [Android Memory] Android Lint简介(转载)

    英文原文:http://tools.android.com/tips/lint  参照文章:http://blog.csdn.net/thl789/article/details/8037473 转载 ...

  6. OC内存管理(MRC)

    首先说明一下几块存储区域: 栈区(局部变量.函数参数值) 堆区(对象.手动申请/释放内存) BSS区(未初始化的全局变量.未初始化的静态数据) 常量区(字符串常量以及初始化后的全局变量.初始化后的静态 ...

  7. 用例视图 Use Case View(rose)

    找开Rose工具,选择用例视图  Use Case View 先看看这个视图下面都有哪些工具,都能做一些什么: 下面详细说一下: 用例视图下面有工具: 一:选择工具 二:文本框Text Box 三:注 ...

  8. svn 日志版本回滚

    [root@v01 online]# svn diff -r 9:8 Index: index.html =============================================== ...

  9. 如何 ︰ 执行批量更新和插入使用.NET 提供程序在 C#.NET OpenXML

    https://support.microsoft.com/zh-cn/kb/315968 如何 ︰ 执行批量更新和插入使用.NET 提供程序在 C#.NET OpenXML Email Prin ...

  10. String.split使用竖线做为分隔符

    String.split使用竖线做为分隔符时会发现得到的数组不对,每个字符都被拆分成数组里的一个值: 解决办法:竖线需要转义才可以作为split的参数,String.split("\\|&q ...