Codeforces

洛谷:咕咕咕


CF少有的大数据结构题。


思路

考虑一些欧拉函数的性质:

\[\varphi(p)=p-1\\
\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
\]

有上面三个就够了。

要求

\[\varphi(\prod a_i)
\]

可以考虑把\(\prod a_i\)拆成

\[\prod p_i^{k_i}
\]

则有

\[\begin{align*}
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? [线段树,欧拉函数]的更多相关文章

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

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

  2. 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}\) 由欧拉函数是积性函数得: \[ ...

  3. BZOJ 3813--奇数国(线段树&欧拉函数&乘法逆元&状态压缩)

    3813: 奇数国 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 755  Solved: 432[Submit][Status][Discuss] ...

  4. 【bzoj3813】: 奇数国 数论-线段树-欧拉函数

    [bzoj3813]: 奇数国 题意:给定一个序列,每个元素可以分解为最小的60个素数的形式.(x=p1^k1*p2^k2*......p60^k60)(p1=2,p2=3,…,p60=281) 支持 ...

  5. [bzoj3813] 奇数国 [线段树+欧拉函数]

    题面 传送门 思路 这题目是真的难读......阅读理解题啊...... 但是理解了以后就发现,题目等价于: 给你一个区间,支持单点修改,以及查询一段区间的乘积的欧拉函数值,这个答案对19961993 ...

  6. 线段树+欧拉函数——cf1114F

    调了半天,写线段树老是写炸 /* 两个操作 1.区间乘法 2.区间乘积询问欧拉函数 欧拉函数计算公式 phi(mul(ai))=mul(ai) * (p1-1)/p1 * (p2-1)/p2 * .. ...

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

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

  8. BZOJ4869 六省联考2017相逢是问候(线段树+欧拉函数)

    由扩展欧拉定理,a^(a^(a^(……^x)))%p中x作为指数的模数应该是φ(φ(φ(φ(……p)))),而p取log次φ就会变为1,也即每个位置一旦被修改一定次数后就会变为定值.线段树维护区间剩余 ...

  9. 【BZOJ3813】奇数国 线段树+欧拉函数

    [BZOJ3813]奇数国 Description 给定一个序列,每次改变一个位置的数,或是询问一段区间的数的乘积的phi值.每个数都可以表示成前60个质数的若干次方的乘积. Sample Input ...

随机推荐

  1. DosBox 的 DOSBOX.CONF 的详细配置说

    1.首先下载 DOSbox 0.72 版.   2.下载完毕,开始安装.安装到任意目录均可.安装完毕会在开始菜单生成程序组,DOSBox.conf 文件是 DOSbox 的配置文件,保持默认配置就可 ...

  2. Android GreenDao使用教程

    1.在build.gradle里添加相关依赖 apply plugin: 'org.greenrobot.greendao' buildscript { repositories { mavenCen ...

  3. SCTP一到多式流分回射服程序

    一.服务器程序 #include <stdlib.h> #include <string.h> #include <strings.h> #include < ...

  4. 十二、文件和目录——Linux文件系统结构

    12.1 Linux文件系统结构 12.1.1 文件操作基本元素 文件操作相关的最基本元素是:目录结构,索引节点和文件的数据本身 目录结构(目录项) 索引节点(i 节点) 文件的数据 12.1.2 文 ...

  5. 20155324 2016-2017-2 《Java程序设计》第6周学习总结

    20155324 2016-2017-2 <Java程序设计>第6周学习总结 教材学习内容总结 InputStream与OutputStream 串流设计 1.串流:Java将输入/输出抽 ...

  6. 第20月第9天 paddlepaddle

    1. http://staging.paddlepaddle.org/docs/develop/book/02.recognize_digits/index.cn.html

  7. Luogu P2490「JSOI2016」黑白棋

    我博弈基础好差.. Luogu P2490 题意 有一个长度为$ n$的棋盘,黑白相间的放$ k$个棋子,保证$ k$是偶数且最左边为白子 每次小$ A$可以移动不超过$ d$个白子,然后小$ B$可 ...

  8. centos7 安装.net core的方法

    安装: sudo yum install libunwind libicu curl -sSL -o dotnet.tar.gz https://go.microsoft.com/fwlink/?li ...

  9. 移动端300ms延迟解决方法在vue 里面的一些小坑

    话不多说上图: 至于import为什么会报错,瞅下面这个图: 总结:要搞懂个必须了解下es6的解构赋值才能在这方面装逼,网上资料一大堆自行百度.

  10. BigDecimal实现末尾去掉无用0

    BigDecimal 原生提供了 stripTrailingZeros 方法可以实现去掉末尾的 0,然后使用 toPlainString 可以输出数值,注意这里如果使用 toString()  会变成 ...