题目大意:给你一个序列,求出指定区间的(l<=i<=r) mod 1000777 的值

还复习了欧拉函数以及线性筛逆元

考虑欧拉函数的的性质,(l<=i<=r),等价于 (p[j]是区间内所有出现过的质数)

那么考虑找出区间内所有出现过的质数,这思路和HH的项链是不是很像??

由于此题强制在线,所以把树状数组替换成了主席树而已

原来我以前写的主席树一直都是错的......还好推出了我原来错误代码的反例

在继承上一个树的信息时,注意不要破坏现在的树

 #include <cstdio>
#include <cstring>
#include <algorithm>
#define ll long long
#define il inline
#define N 50010
#define maxn 1000000
#define mod 1000777
using namespace std; int n,q,ctp,tot;
int root[N];
int pr[maxn+],use[maxn+],lst[maxn+];
ll a[N],inv[mod+],nxt[maxn+];
struct Seg{ll sum;int ls,rs;}seg[N*]; //re
void prime_inv()
{
for(int i=;i<=maxn;i++)
{
if(!use[i])
pr[++ctp]=i,nxt[i]=i;
for(int j=;j<=ctp&&i*pr[j]<=maxn;j++){
use[i*pr[j]]=,nxt[i*pr[j]]=pr[j];
if(i%pr[j]==) break;
}
}
inv[]=inv[]=;
for(ll i=;i<mod;i++)
inv[i]=(mod-mod/i)*inv[mod%i]%mod;
}
ll gc()
{
ll ret=,fh=;char p=getchar();
while(p<''||p>'') {if(p=='-')fh=-;p=getchar();}
while(p>=''&&p<='') {ret=(ret<<)+(ret<<)+p-'';p=getchar();}
return ret*fh;
}
il void pushup(int rt){seg[rt].sum=(seg[seg[rt].ls].sum*seg[seg[rt].rs].sum)%mod;}
void build(int l,int r,int rt)
{
seg[rt].sum=;
if(l==r)return;
int mid=(l+r)>>;
seg[rt].ls=++tot,build(l,mid,tot);
seg[rt].rs=++tot,build(mid+,r,tot);
}
void update(int x,int l,int r,int rt1,int rt2,ll w)
{
if(l==r) {seg[rt2].sum=(seg[rt2].sum*w)%mod;return;}
int mid=(l+r)>>;
if(x<=mid)
{
if(!seg[rt2].ls||seg[rt1].ls==seg[rt2].ls){
seg[rt2].ls=++tot,seg[seg[rt2].ls].sum=seg[seg[rt1].ls].sum;
if(!seg[rt2].rs)
seg[rt2].rs=seg[rt1].rs;
}
update(x,l,mid,seg[rt1].ls,seg[rt2].ls,w);
}else{
if(!seg[rt2].rs||seg[rt1].rs==seg[rt2].rs){
seg[rt2].rs=++tot,seg[seg[rt2].rs].sum=seg[seg[rt1].rs].sum;
if(!seg[rt2].ls)
seg[rt2].ls=seg[rt1].ls;
}
update(x,mid+,r,seg[rt1].rs,seg[rt2].rs,w);
}
pushup(rt2);
}
ll query(int L,int R,int l,int r,int rt)
{
if(L<=l&&r<=R) return seg[rt].sum;
int mid=(l+r)>>;ll ans=;
if(L<=mid) ans*=query(L,R,l,mid,seg[rt].ls),ans%=mod;
if(R>mid) ans*=query(L,R,mid+,r,seg[rt].rs),ans%=mod;
return ans;
} int main()
{
//freopen("a.in","r",stdin);
//freopen("a.out","w",stdout);
scanf("%d%d",&n,&q);
for(int i=;i<=n;i++) a[i]=gc();
prime_inv();
root[]=++tot;
build(,n,);
ll x,p,w;
for(int i=;i<=n;i++)
{
x=a[i],w=a[i],root[i]=++tot;
while(x!=){
p=nxt[x];
if(lst[p])
update(lst[p],,n,root[i-],root[i],(inv[p-]*p)%mod);
lst[p]=i;
x/=p,w=((w*(p-(ll))%mod)*inv[p])%mod;
while(x%p==) x/=p;
}
update(i,,n,root[i-],root[i],w);
}
ll l,r,ans=;
for(int i=;i<=q;i++)
{
l=gc(),r=gc();
l^=ans,r^=ans;
ans=query(l,r,,n,root[r]);
printf("%lld\n",ans);
}
return ;
}

BZOJ 4026 dC Loves Number Theory (主席树+数论+欧拉函数)的更多相关文章

  1. bzoj 4026 dC Loves Number Theory 主席树+欧拉函数

    题目描述 dC 在秒了BZOJ 上所有的数论题后,感觉萌萌哒,想出了这么一道水题,来拯救日益枯竭的水题资源.给定一个长度为 n的正整数序列A,有q次询问,每次询问一段区间内所有元素乘积的φ(φ(n)代 ...

  2. bzoj 4026 dC Loves Number Theory

    把我写吐了 太弱了 首先按照欧拉函数性质 我只需要统计区间不同质数个数就好了 一眼主席树 其次我被卡了分解质因数这里 可以通过质数筛时就建边解决 不够灵性啊,不知道如何改 #include<bi ...

  3. BZOJ 4026: dC Loves Number Theory 可持久化线段树 + 欧拉函数 + 数学

    Code: #include <bits/stdc++.h> #define ll long long #define maxn 50207 #define setIO(s) freope ...

  4. [bzoj4026]dC Loves Number Theory_主席树_质因数分解_欧拉函数

    dC Loves Number Theory 题目大意:dC 在秒了BZOJ 上所有的数论题后,感觉萌萌哒,想出了这么一道水题,来拯救日益枯竭的水题资源. 给定一个长度为 n的正整数序列A,有q次询问 ...

  5. [BZOJ4026]dC Loves Number Theory(线段树)

    根据欧拉函数的定义式可知,可以先算出a[l]*a[l+1]*...*a[r]的值,然后枚举所有存在的质因子*(p-1)/p. 发现这里区间中一个质因子只要计算一次,所以指计算“上一个同色点在区间外”的 ...

  6. 【BZOJ4026】dC Loves Number Theory 分解质因数+主席树

    [BZOJ4026]dC Loves Number Theory Description  dC 在秒了BZOJ 上所有的数论题后,感觉萌萌哒,想出了这么一道水题,来拯救日益枯竭的水题资源.    给 ...

  7. 【bzoj4026】dC Loves Number Theory 可持久化线段树

    题目描述 dC 在秒了BZOJ 上所有的数论题后,感觉萌萌哒,想出了这么一道水题,来拯救日益枯竭的水题资源.  给定一个长度为 n的正整数序列A,有q次询问,每次询问一段区间内所有元素乘积的φ(φ(n ...

  8. [BZOJ4026]dC Loves Number Theory 欧拉函数+线段树

    链接 题意:给定长度为 \(n\) 的序列 A,每次求区间 \([l,r]\) 的乘积的欧拉函数 题解 考虑离线怎么搞,将询问按右端点排序,然后按顺序扫这个序列 对于每个 \(A_i\) ,枚举它的质 ...

  9. bzoj 2818 GCD 数论 欧拉函数

    bzoj[2818]Gcd Description 给定整数N,求1<=x,y<=N且Gcd(x,y)为素数的数对(x,y)有多少对. Input 一个整数N Output 如题 Samp ...

随机推荐

  1. javascript的带操作符的赋值运算

    看犀牛书发现的问题 下面两个表达式 表达式一 data[i++] *= 2; 表达式二 data[i++] = data[i++] * 2;   var data = [7,8,9]; var i = ...

  2. HDU 2522 A simple problem( 分数循环节 )

    链接:Here! 思路:模拟除法,当余数再次出现的时候一定是遇到了循环节( 可看下图例子 ),否则的话继续除法的步骤,直到被除数为 0 . 注意:这道题不需要重新申请一个数组来单独存放答案,如果符合要 ...

  3. ndk,cygwin编译 .so动态库

    注意: ndk .cygwin 安装路径尽量要和sdk放到一个磁盘里,设置环境变量. 例如D: 根目录  变量名:ndk   值:/cygdrive/d/android-ndk-r8e 打开cygwi ...

  4. cliendataset中自增长字段的处理

    cliendataset中自增长字段的处理: id:自增长字段. 在client中的处理方法:clientdataset.Fields.FieldByName('id').ReadOnly:=Fals ...

  5. 【ACM-ICPC 2018 沈阳赛区网络预赛 K】Supreme Number

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 显然每个数字只可能是1,3,5,7 然后如果3,5,7这些数字出现两次以上.显然两个3||5||7都能被11整除. 然后1的话最多能 ...

  6. php RSA 简单实现

    这是rsa_private_key.pem-----BEGIN PRIVATE KEY----- MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQC ...

  7. Fiddler 无法监测WCF通信疑问

    别人的可以检测到通信,我的为什么不行呢? 使用的是basicHttp协议,应该可以的啊,着的是非常奇怪

  8. [SharePoint][SharePoint Designer 入门经典]Chapter13 客户端Silverlight编程

    1.使用Silverlight,CAML和Linq取得数据 2.编程性创建更新删除列表数据项 3.修饰列表和库的配置 4.管理文件和文件夹 5.修改快速启动和顶部导航条 [使用Silverlight, ...

  9. SSH学习之中的一个 OpenSSH基本使用

    在Linux系统中.OpenSSH是眼下最流行的远程系统登录与文件传输应用,也是传统Telenet.FTP和R系列等网络应用的换代产品. 当中,ssh(Secure Shell)能够替代telnet. ...

  10. 婚礼上的谎言(C++实现)

    #include<iostream> using namespace std; void main(void) { int a,b,c; char DD,EE,FF; for (a=1;a ...