bzoj 4026: dC Loves Number Theory 可持久化线段树
来源:互联网 发布:怎样查nginx的版本 编辑:程序博客网 时间:2024/06/07 05:36
题意
给出一个长度为n的序列A,有q个询问,每次询问
n<=50000,q<=100000,Ai<=1000000
分析
又学到了新姿势。
首先考虑如何强制在线求一个区间内不同数的个数。
我们对序列建可持久化线段树,线段树下标表示位置而不是权值。对于位置i上的数x,我们把i的可持久化线段树上的位置i加上1。对于上一个出现了x的位置j,我们把i的可持久化线段树上的位置j减去1。假设要查询区间[l,r],那么就直接查询r的可持久化线段树上的区间[l,r]即可。正确性的话只要随便yy一下就比较显然了。
现在考虑这一题怎么做。
显然我们要求的是
代码
#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<algorithm>using namespace std;typedef long long LL;const int N=50005;const int M=1000005;const int MOD=1000777;int n,q,prime[M],tot,ny[M],ny1[M],low[M],a[N],sz,root[N],ls[M];bool not_prime[M];struct tree{int l,r,mul,s;}t[N*200];int read(){ int x=0,f=1;char ch=getchar(); while (ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while (ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f;}int ksm(int x,int y){ int ans=1; while (y) { if (y&1) ans=(LL)ans*x%MOD; x=(LL)x*x%MOD;y>>=1; } return ans;}void get_prime(int n){ for (int i=2;i<=n;i++) { if (!not_prime[i]) prime[++tot]=i,low[i]=tot; for (int j=1;j<=tot&&i*prime[j]<=n;j++) { not_prime[i*prime[j]]=1; low[i*prime[j]]=j; if (i%prime[j]==0) break; } }}void build(int &d,int l,int r){ d=++sz; if (l==r) { t[d].mul=a[l];t[d].s=1; return; } int mid=(l+r)/2; build(t[d].l,l,mid);build(t[d].r,mid+1,r); t[d].mul=(LL)t[t[d].l].mul*t[t[d].r].mul%MOD; t[d].s=(LL)t[t[d].l].s*t[t[d].r].s%MOD;}void ins(int &d,int p,int l,int r,int x,int y){ d=++sz;t[d]=t[p];t[d].s=(LL)t[d].s*y%MOD; if (l==r) return; int mid=(l+r)/2; if (x<=mid) ins(t[d].l,t[p].l,l,mid,x,y); else ins(t[d].r,t[p].r,mid+1,r,x,y);}int query(int d,int l,int r,int x,int y){ if (x>y) return 1; if (l==x&&r==y) return (LL)t[d].mul*t[d].s%MOD; int mid=(l+r)/2; return (LL)query(t[d].l,l,mid,x,min(y,mid))*query(t[d].r,mid+1,r,max(x,mid+1),y)%MOD;}int main(){ get_prime(1000000); for (int i=1;i<=tot;i++) ny[i]=ksm(prime[i],MOD-2),ny1[i]=ksm(prime[i]-1,MOD-2); n=read();q=read(); for (int i=1;i<=n;i++) a[i]=read(); build(root[0],1,n); for (int i=1;i<=n;i++) { int tmp=a[i];root[i]=root[i-1]; while (tmp>1) { int w=low[tmp]; while (tmp%prime[w]==0) tmp/=prime[w]; if (ls[w]) ins(root[i],root[i],1,n,ls[w],(LL)prime[w]*ny1[w]%MOD); ins(root[i],root[i],1,n,i,(LL)(prime[w]-1)*ny[w]%MOD); ls[w]=i; } } int ans=0; while (q--) { int l=read()^ans,r=read()^ans; printf("%d\n",ans=query(root[r],1,n,l,r)); } return 0;}
阅读全文
0 0
- BZOJ 4026 dC Loves Number Theory 分块+十字链表/可持久化线段树
- bzoj 4026: dC Loves Number Theory 可持久化线段树
- bzoj 4026 dC Loves Number Theory
- BZOJ 4026 dC Loves Number Theory 主席树
- BZOJ 2653 可持久化线段树
- BZOJ 3673 && BZOJ 3674 可持久化线段树
- bzoj 4477: [Jsoi2015]字符串树 可持久化线段树
- BZOJ 2653 middle 二分答案+可持久化线段树
- BZOJ 3772 精神污染 可持久化线段树
- [bzoj]-1901-Zju2112 Dynamic Rankings-可持久化线段树
- BZOJ 3658 Jabberwocky 可持久化线段树+分治
- BZOJ 3524 [Poi2014]Couriers 可持久化线段树
- BZOJ-3524 Couriers 可持久化线段树
- bzoj 2223: [Coci 2009]PATULJCI 可持久化线段树
- bzoj 3166 [Heoi2013]Alo 可持久化trie 线段树
- BZOJ 2588 [可持久化线段树][lca]
- bzoj 3524: [Poi2014]Couriers 可持久化线段树
- [BZOJ 3524][Poi2014]Couriers:可持久化线段树
- Remove Element
- USTCOJ 1127 Laser in Cuboids (思路+容斥原理)
- sqrtx
- oracle日期转换
- 流运算符为什么不能重载为成员函数,只能用友元函数重载
- bzoj 4026: dC Loves Number Theory 可持久化线段树
- EL表达式详解
- 在Mac上安装TensorFlow
- 使用Sublime Text 3编辑markdown
- C语言——自定义头文件
- Spring AOP面向切面编程
- 转变成了一种新的类型。
- Redis数据类型--Set(集合)
- python获取bing上的壁纸