Codeforces 1114F Please, another Queries on Array? [线段树,欧拉函数]
洛谷:咕咕咕
CF少有的大数据结构题。
思路
考虑一些欧拉函数的性质:
\varphi(p^k)=p^{k-1}\times (p-1)=p^k \times \frac{p-1}{p},k>0\\
\varphi(ab)=\varphi(a)\varphi(b),gcd(a,b)=1\\
\dots
\]
有上面三个就够了。
要求
\]
可以考虑把\(\prod a_i\)拆成
\]
则有
ans&=\varphi(\prod a_i)\\
&=\prod \varphi(p_i ^{k_i})\\
&=\prod p_i ^{k_i}\times \frac{p_i-1}{p_i}\\
&=\prod a_i \prod \frac{p_i-1}{p_i}
\end{align*}
\]
发现前面那个只和一段的积有关,后面只和每个质数是否出现有关。
于是可以维护区间积、区间是否出现。筛一下发现\(\le 300\)的质数只有\(62\)个,状压即可。
复杂度\(O(n\log n+q\log^2 n)\),鬼知道这东西怎么跑过去\(n=4\times 10^5,q=2\times 10^5\)的……CF机子厉害呀。
代码
#include<bits/stdc++.h>
namespace my_std{
using namespace std;
#define pll pair<ll,ll>
#define fir first
#define sec second
#define MP make_pair
#define rep(i,x,y) for (int i=(x);i<=(y);i++)
#define drep(i,x,y) for (int i=(x);i>=(y);i--)
#define go(x) for (int i=head[x];i;i=edge[i].nxt)
#define sz 404040
#define mod (ll(1e9+7))
typedef long long ll;
typedef double db;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
template<typename T>inline T rnd(T l,T r) {return uniform_int_distribution<T>(l,r)(rng);}
template<typename T>inline void read(T& t)
{
t=0;char f=0,ch=getchar();double d=0.1;
while(ch>'9'||ch<'0') f|=(ch=='-'),ch=getchar();
while(ch<='9'&&ch>='0') t=t*10+ch-48,ch=getchar();
if(ch=='.'){ch=getchar();while(ch<='9'&&ch>='0') t+=d*(ch^48),d*=0.1,ch=getchar();}
t=(f?-t:t);
}
template<typename T,typename... Args>inline void read(T& t,Args&... args){read(t); read(args...);}
void file()
{
#ifndef ONLINE_JUDGE
freopen("a.txt","r",stdin);
#endif
}
#ifdef mod
ll ksm(ll x,int y){ll ret=1;for (;y;y>>=1,x=x*x%mod) if (y&1) ret=ret*x%mod;return ret;}
ll inv(ll x){return ksm(x,mod-2);}
#else
ll ksm(ll x,int y){ll ret=1;for (;y;y>>=1,x=x*x) if (y&1) ret=ret*x;return ret;}
#endif
// inline ll mul(ll a,ll b){ll d=(ll)(a*(double)b/mod+0.5);ll ret=a*b-d*mod;if (ret<0) ret+=mod;return ret;}
}
using namespace my_std;
int n,Q;
int pri[66],cnt;
bool npri[333];
void init()
{
int n=300;
#define xx (i*pri[j])
rep(i,2,n)
{
if (!npri[i]) pri[++cnt]=i;
rep(j,1,cnt)
{
if (xx>n) break;
npri[xx]=1;
if (i%pri[j]==0) break;
}
}
#undef xx
}
ll tr[sz<<2],tag[sz<<2];
ll S[sz<<2],tg[sz<<2];
#define ls k<<1
#define rs k<<1|1
#define lson ls,l,mid
#define rson rs,mid+1,r
void Mul(int k,int l,int r,ll mul){tag[k]=tag[k]*mul%mod;tr[k]=tr[k]*ksm(mul,r-l+1)%mod;}
void Or(int k,ll s){S[k]|=s;tg[k]|=s;}
void pushdown(int k,int l,int r)
{
int mid=(l+r)>>1;
if (tag[k]!=1) { Mul(lson,tag[k]); Mul(rson,tag[k]); }
Or(ls,tg[k]);Or(rs,tg[k]);
tag[k]=1;tg[k]=0;
}
void pushup(int k){tr[k]=tr[ls]*tr[rs]%mod;S[k]=S[ls]|S[rs];}
void update(int k,int l,int r,int x,int y,ll mul,ll s)
{
if (x<=l&&r<=y) return Mul(k,l,r,mul),Or(k,s);
int mid=(l+r)>>1;
pushdown(k,l,r);
if (x<=mid) update(lson,x,y,mul,s);
if (y>mid) update(rson,x,y,mul,s);
pushup(k);
}
pll query(int k,int l,int r,int x,int y)
{
if (x<=l&&r<=y) return MP(tr[k],S[k]);
pushdown(k,l,r);
int mid=(l+r)>>1;
pll ret(1,0),L,R;
if (x<=mid) L=query(lson,x,y),ret.fir=ret.fir*L.fir%mod,ret.sec|=L.sec;
if (y>mid) R=query(rson,x,y),ret.fir=ret.fir*R.fir%mod,ret.sec|=R.sec;
return ret;
}
void build(int k,int l,int r)
{
tag[k]=1;tg[k]=0;
if (l==r)
{
int x;read(x);
tr[k]=x;
rep(i,1,cnt)
if (x%pri[i]==0)
S[k]|=(1ll<<(i-1));
return;
}
int mid=(l+r)>>1;
build(lson);build(rson);
pushup(k);
}
ll query(int l,int r)
{
pll x=query(1,1,n,l,r);
ll ret=x.fir;
rep(i,1,cnt)
if (x.sec&(1ll<<(i-1)))
ret=ret*(pri[i]-1)%mod*inv(pri[i])%mod;
return ret;
}
void modify(int l,int r,int x)
{
ll s=0;
rep(i,1,cnt)
if (x%pri[i]==0)
s|=(1ll<<(i-1));
update(1,1,n,l,r,x,s);
}
int main()
{
file();
init();
read(n,Q);
build(1,1,n);
char s[10];
int x,y,z;
while (Q--)
{
scanf("%s",s);read(x,y);
if (s[0]=='T') printf("%I64d\n",query(x,y));
else read(z),modify(x,y,z);
}
return 0;
}
Codeforces 1114F Please, another Queries on Array? [线段树,欧拉函数]的更多相关文章
- Codeforces 1114F Please, another Queries on Array? 线段树
Please, another Queries on Array? 利用欧拉函数的计算方法, 用线段树搞一搞就好啦. #include<bits/stdc++.h> #define LL ...
- 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}\) 由欧拉函数是积性函数得: \[ ...
- BZOJ 3813--奇数国(线段树&欧拉函数&乘法逆元&状态压缩)
3813: 奇数国 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 755 Solved: 432[Submit][Status][Discuss] ...
- 【bzoj3813】: 奇数国 数论-线段树-欧拉函数
[bzoj3813]: 奇数国 题意:给定一个序列,每个元素可以分解为最小的60个素数的形式.(x=p1^k1*p2^k2*......p60^k60)(p1=2,p2=3,…,p60=281) 支持 ...
- [bzoj3813] 奇数国 [线段树+欧拉函数]
题面 传送门 思路 这题目是真的难读......阅读理解题啊...... 但是理解了以后就发现,题目等价于: 给你一个区间,支持单点修改,以及查询一段区间的乘积的欧拉函数值,这个答案对19961993 ...
- 线段树+欧拉函数——cf1114F
调了半天,写线段树老是写炸 /* 两个操作 1.区间乘法 2.区间乘积询问欧拉函数 欧拉函数计算公式 phi(mul(ai))=mul(ai) * (p1-1)/p1 * (p2-1)/p2 * .. ...
- Please, another Queries on Array? CodeForces - 1114F (线段树,欧拉函数)
这题刚开始看成求区间$\phi$和了........先说一下区间和的做法吧...... 就是说将题目的操作2改为求$(\sum\limits_{i=l}^{r}\phi(a[i]))\%P$ 首先要知 ...
- BZOJ4869 六省联考2017相逢是问候(线段树+欧拉函数)
由扩展欧拉定理,a^(a^(a^(……^x)))%p中x作为指数的模数应该是φ(φ(φ(φ(……p)))),而p取log次φ就会变为1,也即每个位置一旦被修改一定次数后就会变为定值.线段树维护区间剩余 ...
- 【BZOJ3813】奇数国 线段树+欧拉函数
[BZOJ3813]奇数国 Description 给定一个序列,每次改变一个位置的数,或是询问一段区间的数的乘积的phi值.每个数都可以表示成前60个质数的若干次方的乘积. Sample Input ...
随机推荐
- 解决yum安装mysql时Requires: libc.so.6(GLIBC_2.17)(64bit)
1.yum install mysql-community-server 1 2 3 4 5 6 7 Error: Package: mysql-community-libs-5.7.17-1.el7 ...
- 【全文转载】Precision Helper:最佳免费 CHM 制作软件
跳至内容 善用佳软 IT义工的个人博客: 善用佳软= (善意+善于)应用优秀软件 xbeta= x(未知数)+β(改进测试版) Precision Helper:最佳免费 CHM 制作软件 许多用户都 ...
- 迅为IMX6核心板兼容工业级、商业扩展级、Plus版本核心板
IMX6核心板兼容单核.双核.四核.工业级.汽车级.iMX6Q最新Plus版本,可根据用户需求更换,百变定制,高端产品无忧! iMX6Q核心板(四核商业级) iMX6DL核心板(双核商业级) iMX6 ...
- jupyter notebook出现cannot import name 'create_prompt_application'问题(Died Kernel)
应该是在安装其它python第三方库时更新了prompt-toolkit版本,降级到下面的版本即可: sudo pip install 'prompt-toolkit==1.0.15'
- webpack 配置全局 jQuery 对象
将 lodash 添加到当前模块的上下文中 import _ from 'lodash' 但是你想每个模块都引入的话就特别麻烦,这里有插件可以帮助到您,只需在 webpack.config.js 中配 ...
- Python之List列表的增删改查
序列是Python中最基本的数据结构.序列中的每个元素都分配一个数字 - 它的位置,或索引,第一个索引是0,第二个索引是1,依此类推. Python有6个序列的内置类型,但最常见的是列表和元组. 序列 ...
- 深入理解内存模型JMM
JMM(java memory model)java内存模型主要目标是定义程序中的变量,(此处所指的变量是实例字段.静态字段等,不包含局部变量和函数参数,因为这两种是线程私有无法共享)在虚拟机中存储到 ...
- 虚拟节点操作——DocumentFragment
文章中转站: DocumentFragment对象 createDocumentFragment()用法总结 深入理解DOM节点类型第四篇——文档片段节点DocumentFragment
- ubuntu14.04 Samba服务无法访问 网络名不再可用的问题
参考链接 : https://blog.csdn.net/liuyixjtu/article/details/54575514
- mysql 查询优化 ~ 优化基础补充
一 简介:此文章是对于 sql通用基础的补充说明 二 虚拟列: mysql虚拟列是mysql5.7的新特性,对于函数计算形成的结果可作为虚拟列,并可以对虚拟列添加索引,这样就能加速sql的运行,不过有 ...