https://codeforces.com/contest/1114/problem/F

欧拉函数 + 区间更新线段树

题意

对一个序列(n<=4e5,a[i]<=300)两种操作:

1. 将a[l,r]的数字乘以x(x<=300)

2. 求\(\varphi(\prod_{i=l}^ra[i])\)对1e9+7取模

题解

欧拉函数性质

  1. 假如\(p\)是一个质数,\(\varphi(p)=p-1\),\(\varphi(p^k)=p^{k-1}*(p-1)=p^k*\frac{p-1}{p}\)
  2. 假如p,q互质,\(\varphi(p*q)=\varphi(p)*\varphi(q)\)
  3. 对于一个正整数n,\(\varphi(n)=n*\frac{p_1-1}{p_1}*...*\frac{p_n-1}{p_n}\)
  • 对于每个数分开维护\(n\)和\(\frac{p_1-1}{p_1}*...*\frac{p_n-1}{p_n}\),因为所有数只有300大,有62位素数,所以可以用位运算维护后半部分,剩下前半部分就是维护数的乘积

处理

  • 开两个标记数组,ly[]维护乘积的延迟标记,st[]维护位运算的延迟标记
  • 每次区间操作找到合适的区间就直接修改,需要向下递归前才向下推标记
  • 预处理出x(x<=300)每个数的素因子bit[],可以在埃式筛的过程中处理
  • 查询的时候,需要用两个信息用array<ll,2>,

    附上重载加号代码
array<ll,2> operator +(array<ll,2> a,array<ll,2> b){
return {a[0]*b[0]%P,a[1]|b[1]};
}

代码(区间修改线段树板子)

#include<bits/stdc++.h>
#define P 1000000007
#define ls (o<<1)
#define rs (o<<1|1)
#define ll long long
#define M 1600000
using namespace std;
ll x[M],s[M],ly[M],st[M];
ll bit[305],pr[305],inv[305];
int vi[305];
ll a[400005],tp,X,cnt,i;
int n,q,l,r;
char S[20];
array<ll,2>ans;
array<ll,2> operator +(array<ll,2> a,array<ll,2> b){
return {a[0]*b[0]%P,a[1]|b[1]};
}
ll pw(ll bs,ll x){
ll ans=1;while(x){if(x&1)ans=ans*bs%P;bs=bs*bs%P;x>>=1;}
return ans;
}
void push_up(int o){ //st数组和ly数组同理,作用为标记每次改变量
x[o]=x[ls]*x[rs]%P;
s[o]=s[ls]|s[rs];
ly[o]=1;
st[o]=0;
}
void push_down(int o,int l,int r){ //更新子节点信息,将本节点标记去掉
int mid=(l+r)/2;
if(ly[o]>1){
ly[ls]=ly[ls]*ly[o]%P;
ly[rs]=ly[rs]*ly[o]%P;
s[ls]=s[ls]|st[o];
st[ls]=st[ls]|st[o];
s[rs]=s[rs]|st[o];
st[rs]=st[rs]|st[o];
x[ls]=x[ls]*pw(ly[o],mid-l+1)%P;
x[rs]=x[rs]*pw(ly[o],r-mid)%P;
ly[o]=1;
st[o]=0;
}
} void build(int o,int l,int r){
if(l==r){
ly[o]=x[o]=a[l];
st[o]=s[o]=bit[a[l]];
return;
}
int mid=(l+r)/2;
build(ls,l,mid);build(rs,mid+1,r);
push_up(o);
} array<ll,2> qy(int o,int l,int r,int L,int R){
int mid=(l+r)/2;
array<ll,2>ans={1,0};
if(L<=l&&r<=R){
return {x[o],s[o]};
}
push_down(o,l,r);
if(L<=mid)ans=ans+qy(ls,l,mid,L,R);
if(R>mid)ans=ans+qy(rs,mid+1,r,L,R);
return ans;
} void ud(int o,int l,int r,int L,int R,ll X){
int mid=(l+r)/2; //if(l!=r)push_down(o,l,r); //1.先要将上次的信息传下去不然就会清空了2.并且要特判是不是最后一层
if(L<=l&&r<=R){
ly[o]=X*ly[o]%P;x[o]=x[o]*pw(X,r-l+1)%P;
st[o]|=bit[X];s[o]|=bit[X];
return;
}
push_down(o,l,r); //只要不向下搜就不向下推
if(L<=mid)ud(ls,l,mid,L,R,X);
if(R>mid)ud(rs,mid+1,r,L,R,X);
push_up(o); //更新了才需要向上推
} void init(){
for(int i=2;i<301;i++){
if(!vi[i]){
pr[++cnt]=i;
inv[cnt]=pw(i,P-2);
for(int j=i;j<301;j+=i){
vi[j]=1;bit[j]|=(1ll<<cnt);
}
}
}
} int main(){
init();
cin>>n>>q;
for(i=1;i<=n;i++)scanf("%lld",&a[i]);
build(1,1,n);
while(q--){
scanf("%s",S);
if(S[0]=='M'){
scanf("%d%d%lld",&l,&r,&X);
ud(1,1,n,l,r,X);
}else{
scanf("%d%d",&l,&r);
ans=qy(1,1,n,l,r);
tp=ans[0]%P;
for(i=1;i<63;i++){
if((ans[1]>>i)&1)tp=tp*(pr[i]-1)%P*inv[i]%P;
}
printf("%lld\n",tp);
}
}
}

Codeforces Round #538 (Div. 2) F 欧拉函数 + 区间修改线段树的更多相关文章

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

  2. Codeforces Round #524 (Div. 2) F. Katya and Segments Sets(主席树)

    https://codeforces.com/contest/1080/problem/F 题意 有k个区间,区间的种类有n种,有m个询问(n,m<=1e5,k<=3e5),每次询问a,b ...

  3. Codeforces Round #365 (Div. 2) D. Mishka and Interesting sum 离线+线段树

    题目链接: http://codeforces.com/contest/703/problem/D D. Mishka and Interesting sum time limit per test ...

  4. Codeforces Round #FF (Div. 2)__E. DZY Loves Fibonacci Numbers (CF447) 线段树

    http://codeforces.com/contest/447/problem/E 题意: 给定一个数组, m次操作, 1 l r 表示区间修改, 每次 a[i] +  Fibonacci[i-l ...

  5. Codeforces Round #222 (Div. 1) B. Preparing for the Contest 二分+线段树

    B. Preparing for the Contest 题目连接: http://codeforces.com/contest/377/problem/B Description Soon ther ...

  6. Codeforces Round #345 (Div. 1) D. Zip-line 上升子序列 离线 离散化 线段树

    D. Zip-line 题目连接: http://www.codeforces.com/contest/650/problem/D Description Vasya has decided to b ...

  7. Codeforces Round #538 (Div. 2) D. Flood Fill 【区间dp || LPS (最长回文序列)】

    任意门:http://codeforces.com/contest/1114/problem/D D. Flood Fill time limit per test 2 seconds memory ...

  8. Codeforces Round #370 (Div. 2) E. Memory and Casinos (数学&&概率&&线段树)

    题目链接: http://codeforces.com/contest/712/problem/E 题目大意: 一条直线上有n格,在第i格有pi的可能性向右走一格,1-pi的可能性向左走一格,有2中操 ...

  9. Codeforces Round #250 (Div. 1) D. The Child and Sequence(线段树)

    D. The Child and Sequence time limit per test 4 seconds memory limit per test 256 megabytes input st ...

随机推荐

  1. 《centos系列》配置vim编辑器

    直接wget到~/目录下: wget  http://files.cnblogs.com/ma6174/vimrc.zip 然后进行解压: unzip  -f  vimrc.zip  -d  ~/ 参 ...

  2. 【nlp】中文分词基础原则及正向最大匹配法、逆向最大匹配法、双向最大匹配法的分析

    分词算法设计中的几个基本原则: 1.颗粒度越大越好:用于进行语义分析的文本分词,要求分词结果的颗粒度越大,即单词的字数越多,所能表示的含义越确切,如:“公安局长”可以分为“公安 局长”.“公安局 长” ...

  3. SQL Merge 语法 单表查询

    --项目中需要用到Merg语法,于是去网上查了资料,发现竟然都是多表查询,问题是我只有一张表,于是我纳闷了,后来我灵机一动,就搞定了!--表名:t_login(登录表)--字段:f_userName( ...

  4. 大话listview之设置item监听器无效大坑之一:item设了属性clickable

    今天一个listview设置item监听器居然没有作用: 看了半天,怀疑是item设置了这个属性, 于是删了,果然就可以了. 大坑 ...

  5. Vmware黑屏解决方法

    此原因是显卡性能差,显示选项开启了3D加速导致的,具体修改步骤: 英文路径:VM->Settings->Hardware->Display 在右面的内容栏中将 Accelerate ...

  6. js sort

    排序算法 比较的过程必须通过函数抽象出来.通常规定,对于两个元素x和y,如果认为x < y,则返回-1,如果认为x == y,则返回0,如果认为x > y,则返回1,这样,排序算法就不用关 ...

  7. poj 2785 让和为0 暴力&二分

    题目链接:http://poj.org/problem?id=2785 大意是输入一个n行四列的矩阵,每一列取一个数,就是四个数,求有多少种着四个数相加和为0的情况 首先脑海里想到的第一思维必然是一个 ...

  8. dpdk优化相关 转

    注:本文是参照了一些其他文章,原文地址点击这里. 首先根据这篇文章进行了性能瓶颈的分析 策略与方法 首先根据木桶原理,首先要找到最弱的地方,怎么找往上看↑. 想能优化需要考虑如下: 优化BIOS设置 ...

  9. POJ1966 Cable TV Network

    原题链接 割去点使得无向图不连通,和最小割相似. 我们可以将点转化成边,这样就能跑最小割了. 枚举每两个不能直接到达的点\(S,T\),使得删去一些点(除去这两个点)使得这两个点不连通(若两点能直接到 ...

  10. 转载(windows下安装mysql)

    转载请声明出处:http://blog.csdn.net/u013067166/article/details/49951577             最近重装了系统,去MySQL官网下载了最新的M ...