线段树+欧拉函数——cf1114F
调了半天,写线段树老是写炸
/*
两个操作
1.区间乘法
2.区间乘积询问欧拉函数 欧拉函数计算公式
phi(mul(ai))=mul(ai) * (p1-1)/p1 * (p2-1)/p2 * .. * (pk-1)/pk
因为只有300以内的质数(62个)用一个long long来状态压缩
因此线段树结点维护住区间的质数状态集合S,区间的乘积 操作1 [l,r] x:把x质因数分解,然后更新S,然后再更新乘积,
操作2 [l,r]:询问到区间的状态集合S,区间的乘积,再求逆元进行除法 先把62个质数的逆元求出来 线段树结点维护区间乘积,区间质数集合S,然后两个lazy标记
*/
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define mod 1000000007
#define maxn 400005
ll n,q;
ll p[]={,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,,,,,,,,,};
ll invp[];
ll Pow(ll a,ll b){
ll res=;
while(b){
if(b%)res=res*a%mod;
b>>=;a=a*a%mod;
}
return res;
} ll a[maxn]; #define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
//mul是区间乘积,l_mul是区间乘的lazy
ll msk[maxn<<],mul[maxn<<],l_msk[maxn<<],l_m[maxn<<];
inline ll calc(ll x){
ll res=;
for(ll i=;i<;i++)
if(x%p[i]==) res|=((ll)<<i);
return res;
}
void pushup(int rt){
mul[rt]=mul[rt<<] * mul[rt<<|] % mod;
msk[rt]=msk[rt<<] | msk[rt<<|];
}
void pushdown(int l,int r,int rt){
if(l_msk[rt]!=){
l_msk[rt<<] |= l_msk[rt]; msk[rt<<] |= l_msk[rt];
l_msk[rt<<|] |= l_msk[rt]; msk[rt<<|] |= l_msk[rt];
l_msk[rt]=;
}
if(l_m[rt]!=){//整个区间都要乘
int m=l+r>>;
l_m[rt<<]=l_m[rt<<] * l_m[rt]%mod;
mul[rt<<]=Pow(l_m[rt],m-l+) * mul[rt<<]%mod;
l_m[rt<<|]=l_m[rt<<|] * l_m[rt]%mod;
mul[rt<<|]=Pow(l_m[rt],r-m) * mul[rt<<|]%mod;
l_m[rt]=;
}
}
void build(int l,int r,int rt){
l_msk[rt]=;l_m[rt]=;
if(l==r){
mul[rt]=a[l];
msk[rt]=calc(a[l]);
return ;
}
int m=l+r>>;
build(lson);build(rson);
pushup(rt);
}
void up_mul(int L,int R,ll x,int l,int r,int rt){
if(L<=l && R>=r){
l_m[rt]=l_m[rt]*x%mod;
mul[rt]=mul[rt]*Pow(x,r-l+)%mod;
return;
}
pushdown(l,r,rt);
int m=l+r>>;
if(L<=m)up_mul(L,R,x,lson);
if(R>m)up_mul(L,R,x,rson);
pushup(rt);
}
void up_S(int L,int R,ll S,int l,int r,int rt){
if(L<=l && R>=r){
l_msk[rt]|=S;
msk[rt]|=S;
return;
}
pushdown(l,r,rt);
int m=l+r>>;
if(L<=m) up_S(L,R,S,lson);
if(R>m) up_S(L,R,S,rson);
pushup(rt);
}
ll q_mul(int L,int R,int l,int r,int rt){
if(L<=l && R>=r)return mul[rt];
pushdown(l,r,rt);
int m=l+r>>;
ll res=;
if(L<=m)
res=res*q_mul(L,R,lson)%mod;
if(R>m)
res=res*q_mul(L,R,rson)%mod;
return res;
}
ll q_S(int L,int R,int l,int r,int rt){
if(L<=l && R>=r)return msk[rt];
pushdown(l,r,rt);
int m=l+r>>;
ll S=;
if(L<=m)
S|=q_S(L,R,lson);
if(R>m)
S|=q_S(L,R,rson);
return S;
}
int main(){
for(int i=;i<;i++)
invp[i]=Pow(p[i],mod-);
cin>>n>>q;
for(int i=;i<=n;i++)scanf("%lld",&a[i]); build(,n,); char op[];ll l,r,x;
while(q--){
scanf("%s",op);
if(op[]=='M'){
scanf("%lld%lld%lld",&l,&r,&x);
up_mul(l,r,x,,n,);
ll S=calc(x);
up_S(l,r,S,,n,);
}
else {
scanf("%lld%lld",&l,&r);
ll S=q_S(l,r,,n,);
ll mul=q_mul(l,r,,n,);
for(ll i=;i<;i++)
if(S & ((ll)<<i))
mul=(mul*invp[i]%mod*(p[i]-)%mod);
cout<<mul<<endl;
}
}
return ;
}
线段树+欧拉函数——cf1114F的更多相关文章
- BZOJ 3813--奇数国(线段树&欧拉函数&乘法逆元&状态压缩)
3813: 奇数国 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 755 Solved: 432[Submit][Status][Discuss] ...
- 【bzoj3813】: 奇数国 数论-线段树-欧拉函数
[bzoj3813]: 奇数国 题意:给定一个序列,每个元素可以分解为最小的60个素数的形式.(x=p1^k1*p2^k2*......p60^k60)(p1=2,p2=3,…,p60=281) 支持 ...
- [bzoj3813] 奇数国 [线段树+欧拉函数]
题面 传送门 思路 这题目是真的难读......阅读理解题啊...... 但是理解了以后就发现,题目等价于: 给你一个区间,支持单点修改,以及查询一段区间的乘积的欧拉函数值,这个答案对19961993 ...
- Please, another Queries on Array?(Codeforces Round #538 (Div. 2)F+线段树+欧拉函数+bitset)
题目链接 传送门 题面 思路 设\(x=\prod\limits_{i=l}^{r}a_i\)=\(\prod\limits_{i=1}^{n}p_i^{c_i}\) 由欧拉函数是积性函数得: \[ ...
- Please, another Queries on Array? CodeForces - 1114F (线段树,欧拉函数)
这题刚开始看成求区间$\phi$和了........先说一下区间和的做法吧...... 就是说将题目的操作2改为求$(\sum\limits_{i=l}^{r}\phi(a[i]))\%P$ 首先要知 ...
- BZOJ4869 六省联考2017相逢是问候(线段树+欧拉函数)
由扩展欧拉定理,a^(a^(a^(……^x)))%p中x作为指数的模数应该是φ(φ(φ(φ(……p)))),而p取log次φ就会变为1,也即每个位置一旦被修改一定次数后就会变为定值.线段树维护区间剩余 ...
- 【BZOJ3813】奇数国 线段树+欧拉函数
[BZOJ3813]奇数国 Description 给定一个序列,每次改变一个位置的数,或是询问一段区间的数的乘积的phi值.每个数都可以表示成前60个质数的若干次方的乘积. Sample Input ...
- 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 上所有的数论题后,感觉萌萌哒,想出了这么一道水题,来拯救日益枯 竭 ...
随机推荐
- 轻量级的惰性控件——ViewStub
在开发过程中,有时候,需要这样一种控件,正常情况下不可见,不占用任何布局空间,只在某种特定情况下显示,这种情况下,我们使用一个普通的View,利用设置setVisibility(View.GONE)自 ...
- vim - Vi IMproved, 一个程序员的文本编辑器
总览 (SYNOPSIS) vim [options] [file ..] vim [options] - vim [options] -t tag vim [options] -q [errorfi ...
- Vuejs input 和 textarea 元素中使用 v-model 实现双向数据绑定
demo <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <titl ...
- lua redis 操作
https://redis.io/commands/keys 遍历redis里面的所有key ,还能进行模糊匹配, 这样就省去了对key的手动过滤了 比如 keys term_info* ) &quo ...
- react使用阿里爸爸的iconfont时,不展示的问题
选择使用Unicode时: 正常使用如下,显示也是正常: <i className="iconfont"></i> 使用map去循环时,需将原本的,改成 ...
- Java——package和import关键字
1.8 package和import关键字 1.8.1 package 包其实就是目录,特别是项目比较大,java 文件特别多的情况下,我们应该分目录管理,在java 中称为分包管理,包名称通常采用小 ...
- Delphi中关于菜单的几个技巧
-- 1将菜单项移到菜单栏的最右边 在一些应用程序中,常把一些特殊的菜单项放在菜单栏的最右边(如WPS2000 中的"定制界面"菜单,一些应用程序的帮助菜单),这些菜单项放在菜单栏 ...
- NX二次开发-UFUN工程图表格注释获取某一列的tag函数UF_TABNOT_ask_nth_column
NX9+VS2012 #include <uf.h> #include <uf_tabnot.h> #include <NXOpen/Part.hxx> #incl ...
- 6.4 Data Types
Table 6-1 lists the size, representation, and range of each scalar data type for the C28x compiler. ...
- java-day14
多线程程序访问共享数据会产生安全问题 解决线程安全问题 同步代码块 synchronized(锁对象){ 可能出现线程问题的代码 } 同步方法 修饰符 synchronized 返回值类型 方法名() ...