线段树+欧拉函数——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 上所有的数论题后,感觉萌萌哒,想出了这么一道水题,来拯救日益枯 竭 ...
随机推荐
- VS2013 蛋疼的“AJAX Control Toolkit”安装过程
1.AJAX Control Toolkit 下载问题 方法一. 在vs2013中 工具->NuGet程序包管理器->管理解决方案的NuGet程序包 搜索 ajax z找到 AjaxCon ...
- Echart中X轴数据过多时横向拉动展示
chart.setOption( { tooltip: { trigger: 'axis' }, toolbox: { feature: { saveAsImage: {} } }, grid: { ...
- MySQL日期格式化 利用Mysql的DATE_FORMAT()进行日期格式转换
碰到一个MYSQL的问题,表logstatb中moment字段的内容是"年-月-日 时:分:秒",需要查询匹配“年月日”或“时:分:秒”即可的数据条目,这个时候就可以通过下面的SQ ...
- Redis探索之路(六):Redis的常用命令
一:键值相关命令 1.keys Pattern模糊查询 keys my* 2.exists某个key是否存在 exists key1 3.del 删除一个key del key1 4.expire设置 ...
- leetcode-685-冗余连接②
题目描述: 参考后提交:并查集: class Solution: def findRedundantDirectedConnection(self, edges: List[List[int]]) - ...
- 「题解」:x
问题 A: x 时间限制: 1 Sec 内存限制: 256 MB 题面 题面谢绝公开. 题解 赛时想到了正解并且对拍了很久.对拍没挂,但是评测姬表示我w0了……一脸懵逼. 不难证明,如果对于两个数字 ...
- 26 函数形参值回传问题——C++解决多个return的一般方法
0 引言 在使用数组和vector作为函数的参数进行参数传递并希望得到值的回传时,由于不知道怎么写数组函数形参的引用形式,一直采用vector的引用形式.但是,刚刚测试了一下,发现数组作为参数本身就是 ...
- BZOJ 3779: 重组病毒(线段树+lct+树剖)
题面 escription 黑客们通过对已有的病毒反编译,将许多不同的病毒重组,并重新编译出了新型的重组病毒.这种病毒的繁殖和变异能力极强.为了阻止这种病毒传播,某安全机构策划了一次实验,来研究这种病 ...
- NX二次开发-UFUN获取边的光顺性UF_MODL_ask_edge_smoothness(找相切面)
#include <uf.h> #include <uf_modl.h> #include <uf_obj.h> UF_initialize(); //获取面的所有 ...
- Spring声明式事务的实现方式选择(JDK动态代理与cglib)
1.简介 Spring声明式事务的具体实现方式是动态决定的,与具体配置.以及事务代理对象是否实现接口等有关. 2.使用JDK动态代理的情况 在满足下面两个条件时,Spring会选择JDK动态代理作为声 ...