CF1114F Please, another Queries on Array?
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?的更多相关文章
- CF1114F Please, another Queries on Array?(线段树,数论,欧拉函数,状态压缩)
这题我在考场上也是想出了正解的……但是没调出来. 题目链接:CF原网 题目大意:给一个长度为 $n$ 的序列 $a$,$q$ 个操作:区间乘 $x$,求区间乘积的欧拉函数模 $10^9+7$ 的值. ...
- Codeforces 1114F Please, another Queries on Array? 线段树
Please, another Queries on Array? 利用欧拉函数的计算方法, 用线段树搞一搞就好啦. #include<bits/stdc++.h> #define LL ...
- [Codeforces 266E]More Queries to Array...(线段树+二项式定理)
[Codeforces 266E]More Queries to Array...(线段树+二项式定理) 题面 维护一个长度为\(n\)的序列\(a\),\(m\)个操作 区间赋值为\(x\) 查询\ ...
- 暑假集训单切赛第一场 CF 266E More Queries to Array(线段树+二项式展开式)
比赛时,第二题就是做的这个,当时果断没仔细考虑,直接用线段树暴力求.结果易想而知,超时了. 比赛后搜了搜题解,恍然大悟. 思路:显然用线段树,但是由于每次查询都会有变,所以不可能存储题目中的式子. ...
- [Codeforces266E]More Queries to Array...——线段树
题目链接: Codeforces266E 题目大意:给出一个序列$a$,要求完成$Q$次操作,操作分为两种:1.$l,r,x$,将$[l,r]$的数都变为$x$.2.$l,r,k$,求$\sum\li ...
- Codeforces 1114F Please, another Queries on Array? [线段树,欧拉函数]
Codeforces 洛谷:咕咕咕 CF少有的大数据结构题. 思路 考虑一些欧拉函数的性质: \[ \varphi(p)=p-1\\ \varphi(p^k)=p^{k-1}\times (p-1)= ...
- 【Codeforces 1114F】Please, another Queries on Array?
Codeforces 1114 F 题意:给你一个序列\(a_{1\dots n}\),以及\(q\)次查询,每次查询有两种格式: TOTIENT \(l\) \(r\):求出\(\phi(\Pi_{ ...
- Please, another Queries on Array? CodeForces - 1114F (线段树,欧拉函数)
这题刚开始看成求区间$\phi$和了........先说一下区间和的做法吧...... 就是说将题目的操作2改为求$(\sum\limits_{i=l}^{r}\phi(a[i]))\%P$ 首先要知 ...
- CodeForces 266E More Queries to Array...(线段树+式子展开)
开始觉得是规律题的,自以为是的推了一个规律,结果测试数据都没过....看了love神的博客才发现只是把式子展开就找到规律了.不过挺6的是我虽然想错了,但是维护的的东西没有错,只是改改(改了进两个小时好 ...
随机推荐
- mysql查询日期内的所有日期代码
一.MYSQL查询最近的三个月份的简便方法: select date_format(curdate(),'%Y-%m') from dual union MONTH),'%Y-%m') from du ...
- 转 : JBoss Web和 Tomcat的区别
JBoss Web和 Tomcat的区别 在Web2.0的浪潮中,各种页面技术和框架不断涌现,为服务器端的基础架构提出了更高的稳定性和可扩展性的要求.近年来,作为开源中间件的全 球领导者,JBoss在 ...
- php入门(三)
PHP 面向对象: 在php5中 var就是public的别名. 变量 $this 代表自身的对象. PHP_EOL;为换行符 构造函数+析构函数 <?php class Site { /* 成 ...
- 使用@media screen解决移动web开发的多分辨率问题
当今移动设备的发展已经越来越迅速,移动web开发的需求也越来越多多.许多大平台.大门户都纷纷推出了自己的移动web版网站. 随着移动设备飞速的发展,移动产品的屏幕规格越来越多.从几年前的320×240 ...
- Linux命令详解-pwd
Linux中用 pwd 命令来查看"当前工作目录"的完整路径. 简单得说,每当你在终端进行操作时,你都会有一个当前工作目录. 在不太确定当前位置时,就会使用pwd来判定当前目录在文 ...
- IOS-源代码管理工具(SVN)
一.使用环境 要想利用SVN管理源代码,必须得有2套环境 服务器 用于存储客户端上传的源代码 可以在Windows上安装Visual SVN Server 大部分情况下,公司的开发人员不必亲自搭建SV ...
- 对C++虚函数使用默认参数的注意事项
本文为大便一箩筐的原创内容,转载请注明出处,谢谢:http://www.cnblogs.com/dbylk/ 备忘一个关于虚函数的小知识点 使用多态调用一个类型中定义的虚函数时,编译器会根据指针的当前 ...
- day6-面向对象补充篇--类的特殊成员
先说明一下,今天的内容主要转自师兄张其高的博客http://www.cnblogs.com/zhangqigao/articles/6935221.html 前面我们讲了类的方法,有普通方法,就是我们 ...
- ubuntu 14.04安装c++遇到的问题
这是我在安装c++编译器时遇到的一些问题和解决办法,总结一下希望以后的人能少走弯路 安装g++编译器:sudo apt-get install build-essential build-essent ...
- Poj 1651 Multiplication Puzzle(区间dp)
Multiplication Puzzle Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 10010 Accepted: ...