CF1114F Please, another Queries on Array?

  • 考虑用线段树维护取模后的区间积和真正的区间积所含有的质因子.
  • 每次询问查得这两个值后,一乘一除,即可算出该区间积的欧拉函数.
  • 区间积容易维护,主要考虑如何维护所含的质因子.
  • 注意到 \(a_i\) 和每次乘的 \(x\) 都 \(\leq 300\) , 而 \(300\) 以内的质数恰有 \(62\) 个,所以可以用一个 \(62\) 位的非负整数状压表示一个区间所含的质因子,用 \(long\ long\) 恰能存下.
  • 注意用 \(long\ long\) 状压时需写成 \(1LL<<k\) .
  • 此题难点在于想到分别维护区间积和质因子,以及用状压记录质因子.
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define mp make_pair
#define pii pair<int,int>
inline int read()
{
int x=0;
bool pos=1;
char ch=getchar();
for(;!isdigit(ch);ch=getchar())
if(ch=='-')
pos=0;
for(;isdigit(ch);ch=getchar())
x=x*10+ch-'0';
return pos?x:-x;
}
const int MAXN=4e5+10;
int prime[MAXN]={2,3,5,7,11,13,17,19,23,29,31,37,41,
43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,
127,131,137,139,149,151,157,163,167,173,179,181,191,193,
197,199,211,223,227,229,233,239,241,251,257,263,269,271,
277,281,283,293};
const int siz=62;
const int P=1e9+7;
int a[MAXN];
inline int add(int a,int b)
{
return (a + b) % P;
}
inline int mul(int a,int b)
{
return 1LL * a * b % P;
}
int fpow(int a,int b)
{
int res=1;
while(b)
{
if(b&1)
res=mul(res,a);
a=mul(a,a);
b>>=1;
}
return res;
}
int inv(int x)
{
return fpow(x,P-2);
}
#define root Tree[o]
#define lson Tree[o<<1]
#define rson Tree[o<<1|1]
ll calcdiv(ll x)
{
ll res=0;
for(ll i=0;i<siz;++i)
if(x%prime[i]==0)
res|=(1LL<<i);
return res;
}
struct node{
int l,r;
ll div,prod;
int tag1;
ll tag2;
node()
{
div=0;
prod=1;
tag1=1;
tag2=0;
}
}Tree[MAXN<<2];
void pushup(int o)
{
root.prod=mul(lson.prod,rson.prod);
root.div=lson.div|rson.div;
}
void BuildTree(int o,int l,int r)
{
root.l=l,root.r=r;
if(l==r)
{
root.prod=a[l];
root.div=calcdiv(a[l]);
return;
}
int mid=(l+r)>>1;
BuildTree(o<<1,l,mid);
BuildTree(o<<1|1,mid+1,r);
pushup(o);
}
void Modifiy(int o,int v,ll div)
{
root.tag1=mul(root.tag1,v);
root.tag2|=div;
root.prod=mul(root.prod,fpow(v,root.r-root.l+1));
root.div|=div;
}
void pushdown(int o)
{
if(root.tag2==0)
return;
Modifiy(o<<1,root.tag1,root.tag2);
Modifiy(o<<1|1,root.tag1,root.tag2);
root.tag1=1;
root.tag2=0;
}
void update(int o,int L,int R,int v,ll div)
{
int l=root.l,r=root.r;
if(l>R || r<L)
return;
if(L<=l && r<=R)
{
Modifiy(o,v,div);
return;
}
int mid=(l+r)>>1;
pushdown(o);//修改时也要下传标记
if(L<=mid)
update(o<<1,L,R,v,div);
if(R>mid)
update(o<<1|1,L,R,v,div);
pushup(o);
}
int query(int o,int L,int R,ll &totdiv)
{
int l=root.l,r=root.r;
int res=1;
if(l>R || r<L)
return res;
if(L<=l && r<=R)
{
totdiv|=root.div;
return root.prod;
}
int mid=(l+r)>>1;
pushdown(o);
if(L<=mid)
res=mul(res,query(o<<1,L,R,totdiv));
if(R>mid)
res=mul(res,query(o<<1|1,L,R,totdiv));
return res;
}
int n,m;
int main()
{
// freopen("data.in","r",stdin);
// freopen("data.out","w",stdout);
n=read();
m=read();
for(int i=1;i<=n;++i)
a[i]=read();
BuildTree(1,1,n);
for(int p=1;p<=m;++p)
{
char buf[10];
scanf("%s",buf);
if(buf[0]=='M')
{
int l=read(),r=read(),x=read();
ll div=calcdiv(x);
update(1,l,r,x,div);
}
else
{
assert(buf[0]=='T');
int l=read(),r=read();
ll div=0;
int prod=query(1,l,r,div);
for(ll i=0;i<siz;++i)
{
if((div>>i)&1LL)
prod=mul(prod,prime[i]-1),prod=mul(prod,inv(prime[i]));
}
printf("%d\n",prod);
}
}
return 0;
}

CF1114F Please, another Queries on Array?的更多相关文章

  1. CF1114F Please, another Queries on Array?(线段树,数论,欧拉函数,状态压缩)

    这题我在考场上也是想出了正解的……但是没调出来. 题目链接:CF原网 题目大意:给一个长度为 $n$ 的序列 $a$,$q$ 个操作:区间乘 $x$,求区间乘积的欧拉函数模 $10^9+7$ 的值. ...

  2. Codeforces 1114F Please, another Queries on Array? 线段树

    Please, another Queries on Array? 利用欧拉函数的计算方法, 用线段树搞一搞就好啦. #include<bits/stdc++.h> #define LL ...

  3. [Codeforces 266E]More Queries to Array...(线段树+二项式定理)

    [Codeforces 266E]More Queries to Array...(线段树+二项式定理) 题面 维护一个长度为\(n\)的序列\(a\),\(m\)个操作 区间赋值为\(x\) 查询\ ...

  4. 暑假集训单切赛第一场 CF 266E More Queries to Array(线段树+二项式展开式)

    比赛时,第二题就是做的这个,当时果断没仔细考虑,直接用线段树暴力求.结果易想而知,超时了. 比赛后搜了搜题解,恍然大悟. 思路:显然用线段树,但是由于每次查询都会有变,所以不可能存储题目中的式子.   ...

  5. [Codeforces266E]More Queries to Array...——线段树

    题目链接: Codeforces266E 题目大意:给出一个序列$a$,要求完成$Q$次操作,操作分为两种:1.$l,r,x$,将$[l,r]$的数都变为$x$.2.$l,r,k$,求$\sum\li ...

  6. Codeforces 1114F Please, another Queries on Array? [线段树,欧拉函数]

    Codeforces 洛谷:咕咕咕 CF少有的大数据结构题. 思路 考虑一些欧拉函数的性质: \[ \varphi(p)=p-1\\ \varphi(p^k)=p^{k-1}\times (p-1)= ...

  7. 【Codeforces 1114F】Please, another Queries on Array?

    Codeforces 1114 F 题意:给你一个序列\(a_{1\dots n}\),以及\(q\)次查询,每次查询有两种格式: TOTIENT \(l\) \(r\):求出\(\phi(\Pi_{ ...

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

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

  9. CodeForces 266E More Queries to Array...(线段树+式子展开)

    开始觉得是规律题的,自以为是的推了一个规律,结果测试数据都没过....看了love神的博客才发现只是把式子展开就找到规律了.不过挺6的是我虽然想错了,但是维护的的东西没有错,只是改改(改了进两个小时好 ...

随机推荐

  1. 使用FireFox插件RESTClient工具POST方法?

    下面尝试用Firefox的restclient,来调取api 当然需要打开火狐浏览器安装restclient的插件https://addons.mozilla.org/en-US/firefox/ad ...

  2. 从Github上轻松安装R包—githubinstall包--转载

    1.综述 越来越多的R包正在由世界上不同的人所创建,其中一部分原因是devtools包使得开发R包1变得更加简单.devtools包不仅让开发R包变得简单,而且用于分发R包. 当开发者发布一个R包的时 ...

  3. 获取远程html

    /// <summary> /// 获取远程html /// </summary> /// <param name="url"></par ...

  4. 关于http请求ContentType:application/x-www-form-urlencoded

    在又一次http请求过程中,模拟post请求提交form表单数据一直提示部分参数为空,后面检查发现是缺少ContentType:application/x-www-form-urlencoded的原因 ...

  5. 【Python】更优的字符串格式化方式 -- "format"替代"%s"

    背景 前段时间看了一篇介绍Python的代码技巧的文章,建议格式化字符串时使用"format"代替使用"%",但是没有说明原因.各博客网站介绍相关用法的博客很多 ...

  6. maven笔记(2)

    项目管理利器(Maven)——maven的生命周期和插件Maven的生命周期大概如下:clean compile test package install这几个命令对应了一个项目的完整的构建过程,这几 ...

  7. angular之自定义 directive

    1,指令的创建至少需要一个带有@Directive装饰器修饰的控制器类.@Directive装饰器指定了一个选择器名称,用于指出与此指令相关联的属性的名字. 2,创建一个highlight.direc ...

  8. .Net Core 修改默认的启动端口

    今天无意中发现一个变化,因为很久没看.net core的项目了,发现项目启动的默认端口已经不是5000了,记得很清楚,最早那还是.net core 1.x版本的时候,每次启动都会默认是5000端口号, ...

  9. 以普通用户启动的Vim如何保存需要root权限的文件

    在Linux上工作的朋友很可能遇到过这样一种情况,当你用Vim编辑完一个文件时,运行:wq保存退出,突然蹦出一个错误: E45: 'readonly' option is set (add ! to ...

  10. C++(二十八) — 构造函数的初始化列表

    1.解决的问题: 在 B 类中,组合了一个 A 类对象,其中A类设计了构造函数.由于构造函数的调用规则,设计了构造函数就必须调用,但在定义B类时没有机会初始化A,因此采用构造函数的初始化列表来解决. ...