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 ...
随机推荐
- 使用jQuery插件时避免重复引入jquery.js文件
当一个页面使用多个jQuery插件时,需要避免重复引入jquery.js文件,因为后面映入的jQuery.js文件中定义的jQuery对象会覆盖掉前面的jQuery对象,导致之前定义的jQuery插件 ...
- Coding语言强弱类型且动静态类型简单解析。附图解
话不多说,上图: (以下均以Java来说明) 对于语言的强弱类型: 1.强类型语言:通俗的点来讲,就是对于数据类型,如果开发者定义了一个int数据类型的变量,那么虚拟机就会特别坚定该变量为int,坚决 ...
- JVM(二)垃圾回收
要弄懂JVM的垃圾回收,首先要知道我们要回收什么,在哪回收,什么时候回收. 一.JVM内存模型 java虚拟机把内存模型分为了这么几部分 (1)程序计数器 程序计数器(Program Counter ...
- Frameset 框架
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="index.aspx.c ...
- LOJ #2013「SCOI2016」幸运数字
时限为什么这么大啊 明摆着放多$ log$的做法过啊$QAQ$ LOJ #2013 题意 有$ Q$次询问,每次询问树上一条链,点有点权,你需要选择一些链上的点使得异或和尽量大 点数$ \leq 2* ...
- mfc调用WPFDLL
1.修改MFC项目属性支持CLR 2.打开vcxproj,修改<PropertyGroup Label="Globals"> <PropertyGroup Lab ...
- 0326 iframe和video experience
今天的东西确实不少,很容易混淆,input下的属性太多,form下的属性也不少,内容多点,一时不能熟练掌握,晚上多拿出点时间练练 尤其是 form 和inpu那些属性格外别扭 下午的内嵌视频相对简单主 ...
- Workbook导出excel封装的工具类
在实际中导出excel非常常见,于是自己封装了一个导出数据到excel的工具类,先附上代码,最后会写出实例和解释.支持03和07两个版本的 excel. HSSF导出的是xls的excel,XSSF导 ...
- SpringSecurity自定义用户认证逻辑
⒈处理用户信息获取逻辑 用户信息的获取逻辑是被SpringSecurity封装到UserDetailsService接口里面的 package org.springframework.security ...
- IPC$横向渗透代码实现
思路 IPC$横向渗透的方法,也是病毒常用的扩散方法. 1.建立连接 2.复制文件到共享中C$.D$.E$.F$ 3.获取服务器的时间 3.设定计划任务按时间执行 用到的Windows API 建立网 ...