调了半天,写线段树老是写炸

/*
两个操作
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的更多相关文章

  1. BZOJ 3813--奇数国(线段树&欧拉函数&乘法逆元&状态压缩)

    3813: 奇数国 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 755  Solved: 432[Submit][Status][Discuss] ...

  2. 【bzoj3813】: 奇数国 数论-线段树-欧拉函数

    [bzoj3813]: 奇数国 题意:给定一个序列,每个元素可以分解为最小的60个素数的形式.(x=p1^k1*p2^k2*......p60^k60)(p1=2,p2=3,…,p60=281) 支持 ...

  3. [bzoj3813] 奇数国 [线段树+欧拉函数]

    题面 传送门 思路 这题目是真的难读......阅读理解题啊...... 但是理解了以后就发现,题目等价于: 给你一个区间,支持单点修改,以及查询一段区间的乘积的欧拉函数值,这个答案对19961993 ...

  4. 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}\) 由欧拉函数是积性函数得: \[ ...

  5. Please, another Queries on Array? CodeForces - 1114F (线段树,欧拉函数)

    这题刚开始看成求区间$\phi$和了........先说一下区间和的做法吧...... 就是说将题目的操作2改为求$(\sum\limits_{i=l}^{r}\phi(a[i]))\%P$ 首先要知 ...

  6. BZOJ4869 六省联考2017相逢是问候(线段树+欧拉函数)

    由扩展欧拉定理,a^(a^(a^(……^x)))%p中x作为指数的模数应该是φ(φ(φ(φ(……p)))),而p取log次φ就会变为1,也即每个位置一旦被修改一定次数后就会变为定值.线段树维护区间剩余 ...

  7. 【BZOJ3813】奇数国 线段树+欧拉函数

    [BZOJ3813]奇数国 Description 给定一个序列,每次改变一个位置的数,或是询问一段区间的数的乘积的phi值.每个数都可以表示成前60个质数的若干次方的乘积. Sample Input ...

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

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

  9. BZOJ_4026_dC Loves Number Theory _主席树+欧拉函数

    BZOJ_4026_dC Loves Number Theory _主席树+欧拉函数 Description  dC 在秒了BZOJ 上所有的数论题后,感觉萌萌哒,想出了这么一道水题,来拯救日益枯 竭 ...

随机推荐

  1. OpenResty实现限流的几种方式

      在开发 api 网关的时,做过一些简单的限流,比如说静态拦截和动态拦截:静态拦截说白了就是限流某一个接口在一定时间窗口的请求数.用户可以在系统上给他们的接口配置一个每秒最大调用量,如果超过这个限制 ...

  2. 异步action和redux-thunk理解

    异步action一般指的就是异步action创建函数 action创建函数分为同步action创建函数和异步action创建函数 同步action创建函数(最常见的): function reques ...

  3. mysql开启慢查询报错:

    1.进入mysql命令行:#mysql -uroot -p123456,执行下面的命令开启慢查询报错: set global slow_query_log=on; set global long_qu ...

  4. HTML5表格(table)篇

    初学HTML接触table少不了,但是实际应用的地方也有. 简单说明HTML <table> 标签 定义和用法 <table> 标签定义 HTML 表格. 简单的 HTML 表 ...

  5. Kafka Streams详细

    概述 1 Kafka Streams Kafka Streams.Apache Kafka开源项目的一个组成部分.是一个功能强大,易于使用的库.用于在Kafka上构建高可分布式.拓展性,容错的应用程序 ...

  6. docker搭建jenkins

    这里是在linux环境下安装docker之后,在doucer内安装jenkins --------------------docker 安装 jenkins---------------------- ...

  7. ionic-CSS:ionic 单选框

    ylbtech-ionic-CSS:ionic 单选框 1.返回顶部 1. ionic 单选框 ionic 单选按钮与标准 type="radio" 的 input元素类似.以下展 ...

  8. Python3 From Zero——{最初的意识:002~字符串和文本}

    一.使用多个界定符分割字符串 字符串.split(',')形式只适用于单一分割符的情况:多分割符同时应用的时候,可使用re.split() >>> line = 'asdf fjdk ...

  9. C4D中python初探

    use_name = input('请输入账号') password = input('请输入密码') if use_name == 'alex' and password == 'alex3714' ...

  10. <pygame> 打飞机(小游戏)

    0.游戏的基本实现 ''' 游戏的基本实现 游戏的初始化:设置游戏窗口,绘制图像的初始位置,设定游戏时钟 游戏循环:设置刷新频率,检测用户交互,更新所有图像位置,更新屏幕显示 ''' 1.安装pyga ...