【JZOJ 4638】第三条跑道
来源:互联网 发布:未婚妻 张智霖 知乎 编辑:程序博客网 时间:2024/04/28 04:35
Description
抽象题意:给出一个的序列,求
∏ri=lφ(ai) ,同时兹瓷修改。
Solution
很显然,600以内的质数不会很多,只有109个。
那直接开110棵线段树即可,
每次的修改和维护直接运用欧拉函数的性质即可。
复杂度:
Code
#include<iostream>#include<cstdio>#include<cstdlib>#define foi(i,a,b) for(i=a;i<=b;i++)#define fo(i,a,b) for(int i=a;i<=b;i++)using namespace std;typedef long long LL;const int N=10050,mo=1e8+7;int read(int &n){ char ch=' ';int q=0,w=1; for(;(ch!='-')&&((ch<'0')||(ch>'9'));ch=getchar()); if(ch=='-')w=-1,ch=getchar(); for(;ch>='0' && ch<='9';ch=getchar())q=q*10+ch-48;n=q*w;return n;}int m,n;int bb[N];int Ss[N],pr[N];int b[N*4][120],la[N*4][120];LL b0[N*4];int fs[700][700][2];void fk(int q){ fill(Ss,Ss+1+pr[0],0); if(q==1)return; fo(i,1,pr[0])if(q%pr[i]==0) { Ss[0]++; while(q%pr[i]==0)Ss[i]++,q/=pr[i]; if(q==1)break; }}LL ksm(LL q,LL w){ LL ans=1; while(w) { if(w&1)ans=ans*q%mo; q=q*q%mo;w>>=1; } return ans;}void merge(int e,int q,int w){ b0[e]=b0[q]*b0[w]%mo; fo(i,1,pr[0])b[e][i]=b[q][i]+b[w][i];}void build(int l,int r,int e){ if(l==r) { fk(bb[l]); b0[e]=1; fo(i,1,pr[0])if(Ss[i])b[e][i]=1,b0[e]=b0[e]*(pr[i]-1)%mo*ksm(pr[i],Ss[i]-1)%mo; return; } int t=(l+r)>>1; build(l,t,e*2),build(t+1,r,e*2+1); merge(e,e*2,e*2+1);}void doit(int l,int r,int e){ if(!la[e][0])return; fo(i,1,pr[0])if(la[e][i]) { b0[e]=b0[e]*ksm(pr[i],b[e][i])%mo*ksm(pr[i]-1,r-l+1-b[e][i])%mo*ksm(pr[i],(r-l+1)*(la[e][i]-1))%mo; b[e][i]=r-l+1; if(l!=r)la[e*2][i]+=la[e][i],la[e*2+1][i]+=la[e][i],la[e*2][0]=la[e*2+1][0]=1; la[e][i]=0; } la[e][0]=0;}LL find(int l,int r,int e,int l1,int r1){ if(l==l1&&r==r1){return b0[e];} int t=(l+r)/2; doit(l,t,e*2); doit(t+1,r,e*2+1); LL ans; if(r1<=t)ans=find(l,t,e*2,l1,r1); else if(t<l1)ans=find(t+1,r,e*2+1,l1,r1); else ans=find(l,t,e*2,l1,t)*find(t+1,r,e*2+1,t+1,r1)%mo; merge(e,e*2,e*2+1); return ans;}void change(int l,int r,int e,int l1,int r1){ if(l==l1&&r==r1) { la[e][0]=1; fo(i,1,pr[0])la[e][i]=Ss[i]; doit(l,r,e); return; } int t=(l+r)/2; doit(l,t,e*2),doit(t+1,r,e*2+1); if(r1<=t)change(l,t,e*2,l1,r1); else if(t<l1)change(t+1,r,e*2+1,l1,r1); else change(l,t,e*2,l1,t),change(t+1,r,e*2+1,t+1,r1); merge(e,e*2,e*2+1);}int main(){ int q,w,_,l,r; pr[0]=1;pr[1]=2; fo(i,3,601) { fk(i); if(!Ss[0])pr[++pr[0]]=i; fo(j,1,pr[0]) if(Ss[j])fs[i][++fs[i][0][0]][0]=j,fs[i][fs[i][0][0]][1]=Ss[j]; } read(n); fo(i,1,n)read(bb[i]); build(1,n,1); read(_); while(_--) { read(w),read(l),read(r); if(w)printf("%lld\n",find(1,n,1,l,r)); else { read(q);fk(q); change(1,n,1,l,r); } } return 0;}
0 4
- 【JZOJ 4638】第三条跑道
- 【JZOJ 4638】 第三条跑道
- JZOJ 4638 第三条跑道 【NOIP2016提高组A组7.16】
- 【JZOJ4638】第三条跑道
- 【NOIP模拟】第三条跑道
- [JZOJ4638] 第三条跑道(By--A_Crazy_Czy)
- 【NOIP2016提高组A组7.16】第三条跑道
- 【NOIP2016提高组A组7.16】第三条跑道
- UC头条:从高速公路到飞机跑道的腾挪
- JZOJ 7.10B组第三题 创世纪
- JZOJ 7.9 B组第三题 treecut
- 36辆车,6条跑道,无计时器,最少几次比赛可以选出前三
- 36辆车,6条跑道,无计时器,最少比几次能确定前三名
- 36辆车,6条跑道,无计时器,最少几次比赛可以选出前三
- 36辆车,6条跑道,无计时器,最少几次比赛可以选出前三
- 36辆车,6条跑道,无计时器,最少几次比赛可以选出前三
- 环形跑道
- 第三条 Singleton 模式
- start—py(1、函数)
- C语言函数sscanf()的用法
- 2016.07.16【初中部 NOIP提高组 】模拟赛C
- 漫步微积分四——导数的定义
- Activity 分割动画
- 【JZOJ 4638】第三条跑道
- 页面加载完成后执行的动作
- C语言类型转换
- 浅谈RAID写惩罚(Write Penalty)与IOPS计算
- 二维数组中的查找
- Codeforces Round #204 (Div. 2)
- iOS--PhotoKit简单入门
- 算法竞赛入门经典2.5 2-3倒三角形
- CentOS 7环境下安装Redis