题意

对于正整数 n,定义欧拉函数 φ(n) 为小于等于 n 且与 n 互质的正整数个数。例如
φ(1) = 1, φ(8) = 4。
给定正整数序列 a1, a2, · · · , an,请依次执行 q 个操作,操作有以下三种类型:
0 i x:修改 ai 的值为 x;
1 l r:查询 φ(al + al+1 + · · · + ar) 的值,输出这个值对 10^9 + 7 取模的结果;
2 l r:查询 φ(al × al+1 × · · · × ar) 的值,输出这个值对 10^9 + 7 取模的结果。

1 ≤ i ≤ n, x ≥ 1, 1 ≤ l ≤ r ≤ n。
n ≤ 50000, q ≤ 100000,Ai及x<=40000操作 0 的个数不超过 20000,所有的 ai、
操作 0 中的 i, x 及操作 1,2 中的 l, r 均在给定的限制下内均匀随机生成

分析

首先对于第1问,考虑到加起来的结果最大也就是2e9,我们可以根号时间复杂来算出phi,又考虑数据随机,用线段树或者树状数组维护和,然后一个单次询问是

O(logN+sum−−−−√) O ( l o g N + s u m )

O(logN + \sqrt{sum})

考虑第二问,发现乘起来的话就不能根号时间算phi了,但是我们发现每次乘起来质因子是不会有变化的,而每个只要考虑出现了哪些质因子,每种质因子x对所有乘积的贡献是

x−1x x − 1 x

\frac{x-1}{x}
然后怎么算出现了哪些质因子呢,线段树每个结点开一个bitset,下标为位置,然后预处理出每个数的bitset,修改就对应改掉,询问就把所有的bitset或起来
还有一个操作就是找bitset的每个1可以用这样来找

for(ll i=ans._Find_first();i<ans.size();i=ans._Find_next(i))

质因子个数发现只有4203个,于是就有时间复杂度

O(logN420332∗?) O ( l o g N 4203 32 ∗ ? )

O(logN\frac{4203}{32} * ?)
其中这里的?是1的个数,我们要遍历一遍
考虑 数据随机,我们就可以完成这道题

代码


#include <bits/stdc++.h>
#define ll long longusing namespace std;const ll N = 200010;
const ll mod = 1e9+7;inline ll read()
{ll p=0; ll f=1; char ch=getchar();while(ch<'0' || ch>'9'){if(ch=='-') f=-1; ch=getchar();}while(ch>='0' && ch<='9'){p=p*10+ch-'0'; ch=getchar();}return p*f;
}ll prime[N],pri,inv[N],idx[N]; bool v[N];
bitset<4210> bo[N],ans,pb[N];void init(ll n)
{memset(v,1,sizeof(v)); v[0] = v[1] = 0; pri = 0;for(ll i=2;i<=n;i++){if(v[i]) prime[++pri] = i,idx[i] = pri;for(ll j=1;(j<=pri) && (i*prime[j]<=n);j++){v[i*prime[j]]=0;if(i%prime[j]==0) break;}}inv[0] = inv[1] = 1; for(ll i=2;i<=n;i++) inv[i] = (mod - mod / i) * inv[mod%i] % mod;for(ll i=1;i<=n;i++){ll x=i;for(ll j=1;prime[j]*prime[j]<=x;j++){while(x%prime[j]==0){pb[i].set(j); x/=prime[j];}}if(x!=1) pb[i].set(idx[x]);}
}ll lc[N],rc[N],tot,rt,c[N],s[N];void link(ll &u,ll L,ll R,ll k,ll cc)
{if(!u) u=++tot;if(L==R){bo[u] = pb[cc]; c[u] = s[u] = cc; return ;}ll mid=(L+R)>>1;if(k<=mid) link(lc[u],L,mid,k,cc);else link(rc[u],mid+1,R,k,cc);c[u] = c[lc[u]] + c[rc[u]];s[u] = (s[lc[u]] * s[rc[u]]) % mod;bo[u] = bo[lc[u]] | bo[rc[u]];
}ll qry1(ll u,ll L,ll R,ll l,ll r)
{if(L==l && R==r) return c[u];ll mid=(L+R)>>1;if(r<=mid) return qry1(lc[u],L,mid,l,r);else if(l>mid) return qry1(rc[u],mid+1,R,l,r);else return qry1(lc[u],L,mid,l,mid) + qry1(rc[u],mid+1,R,mid+1,r);
}ll qry2(ll u,ll L,ll R,ll l,ll r)
{if(L==l && R==r){ans |= bo[u]; return s[u];}ll mid=(L+R)>>1;if(r<=mid) return qry2(lc[u],L,mid,l,r);else if(l>mid) return qry2(rc[u],mid+1,R,l,r);else return qry2(lc[u],L,mid,l,mid) * qry2(rc[u],mid+1,R,mid+1,r) % mod;
}ll qpow(ll x,ll k,ll mo){ll ss=1; while(k){if(k&1) ss=ss*x%mo; x=x*x%mo; k>>=1;} return ss;}int main()
{init(40000);ll n = read(); ll m = read();rt=tot=0; for(ll i=1;i<=n;i++) link(rt,1,n,i,read());while(m--){ll op = read();if(op==0){ll k = read(); link(rt,1,n,k,read());}else if(op==1){ll l=read(); ll r=read(); ll sum = qry1(rt,1,n,l,r);ll x = sum;for(ll i=1;prime[i] * prime[i] <= x;i++){if(x%prime[i]==0){sum = sum * inv[prime[i]] % mod * (prime[i] - 1) % mod;while(x%prime[i]==0) x/=prime[i];}}if(x!=1) sum = sum * qpow(x,mod-2,mod) % mod * (x-1) % mod;printf("%lld\n",sum);}else{ll l=read(); ll r=read(); ans.reset();ll sum = qry2(rt,1,n,l,r);for(ll i=ans._Find_first();i<ans.size();i=ans._Find_next(i))sum = sum * inv[prime[i]] % mod * (prime[i]-1) % mod;printf("%lld\n",sum);}}return 0;
}

bzoj 5245: [Fjwc2018]欧拉函数 线段树+bitset相关推荐

  1. [LNOI] 相逢是问候 || 扩展欧拉函数+线段树

    原题为2017六省联考的D1T3 给出一个序列,m次操作,模数p和参数c 操作分为两种: 1.将[l,r]区间内的每个数x变为\(c^x\) 2.求[l,r]区间内数的和%p 首先,我们要了解一些数论 ...

  2. jzoj4638-第三条跑道【欧拉函数,线段树】

    正题 题目大意 要求支持区间乘和区间求∏φ(xi)\prod \varphi(x_i)∏φ(xi​) 解题思路 首先φ(n)=n∗∏(pi−1pi)\varphi(n)=n*\prod (\frac{ ...

  3. bzoj4869: [Shoi2017]相逢是问候(欧拉函数+线段树)

    这题是六省联考的...据说数据还出了点锅,心疼六省选手QAQ 首先要知道扩展欧拉定理... 可以发现每次区间操作都会使模数进行一次phi操作,而一个数最多取logp次phi就会变成1,这时后面的指数就 ...

  4. [BZOJ 4034][HAOI2015]树上操作(欧拉序列+线段树)

    Description 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个 操作,分为三种: 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x 为根的子树中 ...

  5. [CF1603D] Artistic Partition——欧拉函数,线段树优化DP

    [CF1603D] Artistic Partition 题解 问题其实就是要你把 1 ∼ n 1\sim n 1∼n 分成 k k k 段,最小化每一段的 c c c 值的和. 首先我们会想到,如果 ...

  6. Codeforces Round #538 (Div. 2) F. Please, another Queries on Array? 线段树 + 欧拉函数

    传送门 文章目录 题意: 思路: 题意: 给你一个序列aaa,你需要实现两种操作: (1)(1)(1) 将[l,r][l,r][l,r]的aia_iai​都乘rrr. (2)(2)(2) 求ϕ(∏i= ...

  7. bzoj 1409 Password 矩阵快速幂+欧拉函数

    可以发现,该数组的mi就是斐波那契数列 所以要矩阵快速幂搞出第n位 但是斐波那契数列上涨的很快,这就需要欧拉定理了 p^phi(q)%q=1(gcd(p,q)==1) p是素数,所以可以用 然后需要5 ...

  8. BZOJ - 2186 欧拉函数

    题目的意思大概是求1~N!中和M!互质的数的个数 因为对欧拉函数理解不够深刻所以我是分析得到结果的: 当N<=M的时候显然符合要求的数的个数为0: 当N>M的时候我们要求的是1~N!中不含 ...

  9. bzoj 3884: 上帝与集合的正确用法(欧拉函数)

    3884: 上帝与集合的正确用法 Time Limit: 5 Sec  Memory Limit: 128 MB Submit: 2574  Solved: 1151 [Submit][Status] ...

最新文章

  1. 一步一步写算法(之hash表)
  2. 【 FPGA 】FIR 滤波器之半带抽取器(Half-band Decimator)
  3. 使用pytorch最关键的几个点
  4. php接收键盘事件,js获取键盘事件的方法实例
  5. mysql 长时间连接没操作,断开连接
  6. 我的世界服务器指令修改拔刀剑,我的世界拔刀剑Mod 合成刀方法作用
  7. java int 指针_如何在Java中使用指针?
  8. sar分辨率公式_对PAR DAR SAR的理解
  9. cargo 使用国内源镜像,引用 substrate 的 Contracts Pallet Crate 编译错误
  10. 数据结构——>稀疏数组
  11. window 下注册 redis服务
  12. 如何方便的下载csdn博客正文
  13. kutools for word 10(Word工具箱) 附安装教程
  14. ubuntu20 关闭防火墙_ubuntu中如何关闭防火墙
  15. 仿唯品会尺码助手弹框 带箭头叉号的popupwindow BubbleLayout
  16. 图解汽车各部位的名称大全
  17. Pascal小游戏 俄罗斯方块怀旧版
  18. 我的世界服务器怎么设置自动拾取,自动拾取Auto Pickup Mod
  19. Random中的随机数的产生机制
  20. 【战国策】之《齐策·昭阳为楚伐魏》

热门文章

  1. WIN10上使用VM部署虚拟机NAT网络模式下域名解析失败
  2. 无需App!中国移动5G消息数字人民币钱包正式上线
  3. DataX二次开发——(6)kafkareader、kafkawriter的开发
  4. 为MacTex配置Ctex环境
  5. 《神奇的数学》读后感_数学王国_奇妙的数学王国读后感10篇
  6. ViewBag的用法
  7. Server_虚拟机闲谈;
  8. MySQL数据库id主键或密码使用MD5加密
  9. 搞懂它,带你学会高效配置交换机!
  10. USB加密锁(加密狗)复制和破解Key解密