CF1114F Please, another Queries on Array?(线段树,数论,欧拉函数,状态压缩)
这题我在考场上也是想出了正解的……但是没调出来。
题目链接:CF原网
题目大意:给一个长度为 $n$ 的序列 $a$,$q$ 个操作:区间乘 $x$,求区间乘积的欧拉函数模 $10^9+7$ 的值。
$1\le n\le 4\times 10^5,1\le q\le 2\times 10^5,1\le a_i,x\le 300$。时限 5.5s,空限 256MB。
明显线段树。
有一个想法是维护区间积的欧拉函数,但是这样时间复杂度和代码复杂度都很高……
我的做法是维护区间积。而欧拉函数,就是看看区间中包含什么质因子,然后除一下乘一下好了。
区间积就不用说了。
包含什么质因子?难道要开bool数组吗?时间复杂度很高……
经过后台黑科技操作发现 $300$ 以内的质数只有 $62$ 个。明摆着状压的节奏!
好的,这题做完了。细节的东西在代码中都有。
对于我的代码实现来说:(以下令 $k=62$)
建树 $O(kn)$。
合并节点 $O(1)$。
下推标记 $O(\log n)$。
区间乘 $O(\log^2 n+k)$。
查询欧拉函数 $O(\log n+k)$。
总时间复杂度应该是 $O((n+q)k+q\log^2n)$。其实跑得不慢,我跑得最慢的点是1934ms。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=,mod=;
#define lson o<<1,l,mid
#define rson o<<1|1,mid+1,r
#define FOR(i,a,b) for(int i=(a);i<=(b);i++)
#define ROF(i,a,b) for(int i=(a);i>=(b);i--)
#define MEM(x,v) memset(x,v,sizeof(x))
inline int read(){
char ch=getchar();int x=,f=;
while(ch<'' || ch>'') f|=ch=='-',ch=getchar();
while(ch>='' && ch<='') x=x*+ch-'',ch=getchar();
return f?-x:x;
}
int n,q,pri[],pl,a[maxn],inv[],f[],tag1[maxn*]; //tag1表示区间要乘多少
ll tag2[maxn*]; //tag2表示区间会多出哪些质因子(也是压缩过的)
//为什么要两个标记呢?不能直接对tag1分解质因子吗?
//因为tag1乘几遍就会被取模,这样看起来质因子就变了。所以额外加一个tag2表示真的质因子集合。
bool vis[];
void init(){
FOR(i,,){
if(!vis[i]) pri[++pl]=i;
for(int j=;j<=pl && i*pri[j]<=;j++){
vis[i*pri[j]]=true;
if(i%pri[j]==) break;
}
}
inv[]=;
FOR(i,,) inv[i]=mod-1ll*(mod/i)*inv[mod%i]%mod;
FOR(i,,pl) f[i]=1ll*inv[pri[i]]*(pri[i]-)%mod;
//f[i]表示除以p[i],再乘上p[i]-1,便于计算欧拉函数
}
inline int qpow(int a,int b){
int ans=;
for(;b;b>>=,a=1ll*a*a%mod) if(b&) ans=1ll*ans*a%mod;
return ans;
}
struct node{
int pro;ll has;
}nd[maxn*]; //一个线段树节点,pro是区间积,has是区间包含哪些质因子(压缩过的)
void pushup(node &o,node l,node r){ //合并
o.has=l.has|r.has; //直接取或
o.pro=1ll*l.pro*r.pro%mod;
}
void setmult(int o,int l,int r,int x,ll y){ //对第o个节点(管辖[l,r])区间乘x,质因子多了y
tag1[o]=1ll*tag1[o]*x%mod;
tag2[o]|=y;
nd[o].pro=1ll*nd[o].pro*qpow(x,r-l+)%mod; //记得乘r-l+1次方
nd[o].has|=y;
}
void pushdown(int o,int l,int r){ //下传标记
if(!tag2[o]) return;
int mid=(l+r)>>;
setmult(lson,tag1[o],tag2[o]);
setmult(rson,tag1[o],tag2[o]);
tag1[o]=;tag2[o]=; //记得tag1闲置时是1
}
void build(int o,int l,int r){
tag1[o]=;tag2[o]=;
if(l==r){
nd[o].pro=a[l];
FOR(i,,pl) //记录质因子集合
if(a[l]%pri[i]==) nd[o].has|=1ll<<(i-);
return;
}
int mid=(l+r)>>;
build(lson);build(rson);
pushup(nd[o],nd[o<<],nd[o<<|]);
}
void mult(int o,int l,int r,int ql,int qr,int x,ll y){ //外面调用时先把质因子集合弄好,会省时间
if(l>=ql && r<=qr){
setmult(o,l,r,x,y); //直接设上
return;
}
pushdown(o,l,r);
int mid=(l+r)>>;
if(mid>=ql) mult(lson,ql,qr,x,y);
if(mid<qr) mult(rson,ql,qr,x,y);
pushup(nd[o],nd[o<<],nd[o<<|]);
}
node query(int o,int l,int r,int ql,int qr){
if(l>=ql && r<=qr) return nd[o];
pushdown(o,l,r);
int mid=(l+r)>>;
if(mid<ql) return query(rson,ql,qr);
if(mid>=qr) return query(lson,ql,qr);
node ans;
pushup(ans,query(lson,ql,qr),query(rson,ql,qr)); //合并两边
return ans;
}
int main(){
init();
n=read();q=read();
FOR(i,,n) a[i]=read();
build(,,n);
FOR(i,,q){
char op[];
scanf("%s",op);
int l=read(),r=read();
if(op[]=='M'){ //乘操作
int x=read();ll y=;
FOR(i,,pl) if(x%pri[i]==) y|=1ll<<(i-); //先处理质因子集合
mult(,,n,l,r,x,y);
}
else{ //求欧拉函数操作
node ans=query(,,n,l,r);
int s=ans.pro; //区间积
FOR(i,,pl) if(ans.has&(1ll<<(i-))) s=1ll*s*f[i]%mod; //区间含有第i个质数,那就要除以p[i],再乘上p[i]-1
printf("%d\n",s);
}
}
}
CF1114F Please, another Queries on Array?(线段树,数论,欧拉函数,状态压缩)的更多相关文章
- Codeforces 1114F Please, another Queries on Array? [线段树,欧拉函数]
Codeforces 洛谷:咕咕咕 CF少有的大数据结构题. 思路 考虑一些欧拉函数的性质: \[ \varphi(p)=p-1\\ \varphi(p^k)=p^{k-1}\times (p-1)= ...
- BZOJ 4026 dC Loves Number Theory (主席树+数论+欧拉函数)
题目大意:给你一个序列,求出指定区间的(l<=i<=r) mod 1000777 的值 还复习了欧拉函数以及线性筛逆元 考虑欧拉函数的的性质,(l<=i<=r),等价于 (p[ ...
- [Codeforces 266E]More Queries to Array...(线段树+二项式定理)
[Codeforces 266E]More Queries to Array...(线段树+二项式定理) 题面 维护一个长度为\(n\)的序列\(a\),\(m\)个操作 区间赋值为\(x\) 查询\ ...
- Codeforces 1114F Please, another Queries on Array? 线段树
Please, another Queries on Array? 利用欧拉函数的计算方法, 用线段树搞一搞就好啦. #include<bits/stdc++.h> #define LL ...
- 暑假集训单切赛第一场 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 ...
- CF383C Propagating tree (线段树,欧拉序)
\(tag\)没开够\(WA\)了一发... 求出\(dfs\)序,然后按深度分类更新与查询. #include <iostream> #include <cstdio> #i ...
- 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}\) 由欧拉函数是积性函数得: \[ ...
- CF1114F Please, another Queries on Array?
CF1114F Please, another Queries on Array? 考虑用线段树维护取模后的区间积和真正的区间积所含有的质因子. 每次询问查得这两个值后,一乘一除,即可算出该区间积的欧 ...
随机推荐
- core_cm4_simd.h文件是干嘛的?
core_cm4_simd.h文件用于simd指令,即单指令多数据流,这个只有ARMv7架构才有,Cortex m3 m4 m7是ARMv7架构,而Cortex m0 m1是没有的. 所以,在新建Co ...
- Flutter - 退出App
Flutter退出App的方法一般有两种 ①SystemNavigator.pop 推荐 onTap: () async { await pop(); }, static Future<void ...
- 当给DataGrid的Itemssoure属性赋值引起TabControl_SelectionChanged事件
在TabControl的TabItem下布局了DataGrid控件时,当给dg.ItemsSource 赋值时会触发父控件的TabControl_SelectionChanged事件; 类似问题原因可 ...
- Azure Load Balancer : 支持 IPv6
越来越多的网站开始支持 IPv6,即使是哪些只提供 api 服务的站点也需要支持 IPv6,比如苹果应用商店中的 app 早就强制要求服务器端支持 IPv6 了.笔者在前文<Azure Load ...
- 系统、决策、控制研究系列(SSDC)
本类目主要介绍的书籍来自springer的系列书籍中的一本,对于该系列书籍介绍如下: “系统.决策及控制研究”(SSDC)系列涵盖了在广泛认知的系统.决策及控制的各个领域的快速.最新和高质量的最新发展 ...
- ProxySQL实现Mysql读写分离 - 部署手册
ProxySQL是一个高性能的MySQL中间件,拥有强大的规则引擎.ProxySQL是用C++语言开发的,也是percona推的一款中间件,虽然也是一个轻量级产品,但性能很好(据测试,能处理千亿级的数 ...
- jenkins中配置svn 出现absolute path is not allowed
代码: 兵马未动,粮草先行 作者: 传说中的汽水枪 如有错误,请留言指正,欢迎一起探讨. 转载请注明出处. 想用jenkins作自动化部署tomcat. svn代码已经checkout到本地目录了(/ ...
- 第三周作业————————word count
#include <stdio.h> void main() { FILE *fp; , str, word, pu, ch; int g; str = ; word = ; pu = ; ...
- 探秘Java中的String、StringBuilder以及StringBuffer(转载)
探秘Java中String.StringBuilder以及StringBuffer 相信String这个类是Java中使用得最频繁的类之一,并且又是各大公司面试喜欢问到的地方,今天就来和大家一起学习一 ...
- 【转】单片机HEX文件完全解读
转:http://www.eefocus.com/craftor/blog/10-07/193051_8ce59.html Craftor原创,首发于与非网,转载请保留此处. HEX文件,是Intel ...