upd on 2021.9.5:昨天的那个版本被 2-tower 卡爆了,故今天重发一个。

Codeforces 题面传送门 & 洛谷题面传送门

没往“每个数最多只有一个 \(>\sqrt{x}\) 的质因子”这个性质的蒟蒻来一发特别暴力的解法。

首先看到这个强制在线显然无法用 cdq 分治或者扫描线一类离线算法维护,因此考虑主席树或者树套树这一类在线算法。注意到对于一个质因子 \(p\)​​,显然 \(p\)​​ 对一段区间的贡献就是 \(p^\text{maxc}\)​​,其中 \(\text{maxc}\)​​ 表示区间 \([l,r]\)​​ 中 \(p\)​​ 次数的最大值。这个最大值显然不好维护,因此转化为对于每个数 \(p\)​​ 的次数 \(p^c\)​​,它会对哪些区间产生贡献,根据笛卡尔树那一套理论,满足 \([l,r]\)​​ 中 \(p\)​​ 次数的最大值刚好为 \(c\)​​ 的区间左端点形成一个区间 \([L_l,R_l]\)​​,右端点也形成一个区间 \([L_r,R_r]\)​​,因此对于 \(l\in[L_l,R_l],r\in[L_r,R_r]\)​​,\([l,r]\)​​ 区间的答案应乘上 \(p^c\)​​。\(L_l,R_l,L_l,R_r\)​​ 可以单调栈求,当然也可以从小到大将所有 \(c\)​​ 插入 set 中然后在 set 中用 lower_bound 之类的东西求得。由于只有 \(c\ne 0\)​​ 的 \(c\)​​ 是有意义的,而对于所有 \(p\)​​,有意义的 \(c\)​​ 的个数之和应为所有 \(a_i\)​​ 质因子个数之和,而这显然不超过 \(\max\{\omega(n)\}·n\approx 7n\)​​,因此这样复杂度是 \(\mathcal O(7n)\)​​ 或 \(\mathcal O(7n\log n)\)​​​,在可接受范围内。

接下来考虑怎样计算答案。显然经过我们这么一分析,所有贡献都可以转化为以下形式:初始有一个全为 \(1\) 的矩阵 \(a\),有若干次操作:对于 \(i\in[l_1,r_1],j\in[l_2,r_2],a_{i,j}\leftarrow a_{i,j}·v\),求 \(a_{l,r}\)。看到这个设问一眼树套树,直接树套树大概是 \(7n·\log^2n\),空间和时间都很危,我第一次提交大约是 TLE #21。考虑加一点小小的优化,根据复杂度平衡的思想,我们设一个阈值 \(B\)(\(30\sim 50\)),那么对于 \(\le B\) 的质因子,有意义的 \(c\) 的个数可能很多,此时直接 ST 表维护最大值是 \(n\log n\) 的,反而优于树套树的 2log,因此考虑对 \(\le B\) 的质因子每个建一个 ST 表,然后每次询问这些质因子的贡献就暴力遍历即可。

const int MAXN=1e5;
const int MAXV=2e5;
const int MAXP=MAXN<<8;
const int LOG_N=17;
const int MOD=1e9+7;
int n,qu,a[MAXN+5];
int pr[MAXV/6+5],prcnt=0,mnp[MAXV+5];
bitset<MAXV+5> vis;
vector<pii> ps[MAXV+5];
void sieve(int n){
for(int i=2;i<=n;i++){
if(!vis[i]) pr[++prcnt]=i,mnp[i]=i;
for(int j=1;j<=prcnt&&pr[j]*i<=n;j++){
vis[pr[j]*i]=1;mnp[pr[j]*i]=pr[j];
if(i%pr[j]==0) break;
}
}
}
int qpow(int x,int e){
int ret=1;
for(;e;e>>=1,x=1ll*x*x%MOD) if(e&1) ret=1ll*ret*x%MOD;
return ret;
}
struct node{int ch[2],val;} s[MAXP+5];
int rt[MAXN+5],ncnt=0;
void pushup(int k){s[k].val=1ll*s[s[k].ch[0]].val*s[s[k].ch[1]].val%MOD;}
void insert_in(int &k,int l,int r,int p,int v){
if(!k) k=++ncnt,s[k].val=1;
if(l==r) return s[k].val=1ll*s[k].val*v%MOD,void();
int mid=l+r>>1;
if(p<=mid) insert_in(s[k].ch[0],l,mid,p,v);
else insert_in(s[k].ch[1],mid+1,r,p,v);
pushup(k);
}
void insert(int x,int l,int r,int v){
int iv=qpow(v,MOD-2);
for(int i=x;i<=n;i+=(i&(-i))){
insert_in(rt[i],1,n,l,v);
if(r!=n) insert_in(rt[i],1,n,r+1,iv);
}
}
int query_in(int k,int l,int r,int ql,int qr){
if(!k) return 1;if(ql<=l&&r<=qr) return s[k].val;
int mid=l+r>>1;
if(qr<=mid) return query_in(s[k].ch[0],l,mid,ql,qr);
else if(ql>mid) return query_in(s[k].ch[1],mid+1,r,ql,qr);
else return 1ll*query_in(s[k].ch[0],l,mid,ql,mid)*query_in(s[k].ch[1],mid+1,r,mid+1,qr)%MOD;
}
int query(int x,int y){
int ret=1;
for(;x;x&=(x-1)) ret=1ll*ret*query_in(rt[x],1,n,1,y)%MOD;
return ret;
}
void add(int l1,int r1,int l2,int r2,int v){
// printf("%d %d %d %d %d\n",l1,r1,l2,r2,v);
insert(l1,l2,r2,v);if(r1^n) insert(r1+1,l2,r2,qpow(v,MOD-2));
}
int st[11][MAXN+5][LOG_N+2];
int query_st(int x,int l,int r){
int k=31-__builtin_clz(r-l+1);
return max(st[x][l][k],st[x][r-(1<<k)+1][k]);
}
int main(){
scanf("%d",&n,&qu);sieve(MAXV);s[0].val=1;
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
for(int i=1;i<=n;i++){
int tmp=a[i];
while(tmp^1){
int p=mnp[tmp],cnt=0;
while(tmp%p==0) tmp/=p,cnt++;
ps[p].pb(mp(cnt,i));
}
}
for(int i=1;i<=10;i++){
for(pii p:ps[pr[i]]) st[i][p.se][0]=p.fi;
for(int j=1;j<=LOG_N;j++) for(int k=1;k+(1<<j)-1<=n;k++)
st[i][k][j]=max(st[i][k][j-1],st[i][k+(1<<j-1)][j-1]);
}
for(int i=31;i<=MAXV;i++) if(!ps[i].empty()){
sort(ps[i].begin(),ps[i].end());
reverse(ps[i].begin(),ps[i].end());
set<int> st;st.insert(0);st.insert(n+1);
for(pii p:ps[i]){
st.insert(p.se);
set<int>::iterator it=st.find(p.se);
int pre=*--it,nxt=*++ ++it;
// printf("%d %d\n",pre,nxt);
add(pre+1,p.se,p.se,nxt-1,qpow(i,p.fi));
}
} scanf("%d",&qu);int pre=0;
while(qu--){
int x,y;scanf("%d%d",&x,&y);
x=(x+pre)%n+1;y=(y+pre)%n+1;
if(x>y) swap(x,y);
// printf("%d %d\n",x,y);
pre=query(x,y);
for(int i=1;i<=10;i++) pre=1ll*pre*qpow(pr[i],query_st(i,x,y))%MOD;
printf("%d\n",pre);
}
return 0;
}

Codeforces 1422F - Boring Queries(树套树)的更多相关文章

  1. Educational Codeforces Round 56 (Rated for Div. 2) E(1093E) Intersection of Permutations (树套树,pb_ds)

    题意和分析在之前的链接中有:https://www.cnblogs.com/pkgunboat/p/10160741.html 之前补题用三维偏序的cdq的分治A了这道题,但是感觉就算比赛再次遇到类似 ...

  2. BZOJ 3110: [Zjoi2013]K大数查询 [树套树]

    3110: [Zjoi2013]K大数查询 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 6050  Solved: 2007[Submit][Sta ...

  3. BZOJ4170 极光(CDQ分治 或 树套树)

    传送门 BZOJ上的题目没有题面-- [样例输入] 3 5 2 4 3 Query 2 2 Modify 1 3 Query 2 2 Modify 1 2 Query 1 1 [样例输出] 2 3 3 ...

  4. bzoj3262: 陌上花开(树套树)

    #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #i ...

  5. bzoj3295: [Cqoi2011]动态逆序对(树套树)

    #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #i ...

  6. BZOJ 3110 k大数查询 & 树套树

    题意: 有n个位置,每个位置可以看做一个集合,现在要求你实现一个数据结构支持以下功能: 1:在a-b的集合中插入一个数 2:询问a-b集合中所有元素的第k大. SOL: 调得火大! 李建说数据结构题能 ...

  7. BZOJ 3110 树套树 && 永久化标记

    感觉树套树是个非常高深的数据结构.从来没写过 #include <iostream> #include <cstdio> #include <algorithm> ...

  8. 【BZOJ】1901: Zju2112 Dynamic Rankings(区间第k小+树套树)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1901 这题调了我相当长的时间,1wa1a,我是第一次写树套树,这个是树状数组套splay,在每个区间 ...

  9. hdu 4417 Super Mario/树套树

    原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=4417 题意很简单,给定一个序列求一个区间 [L, R,]中小于等于H的元素的个数. 好像函数式线段树可 ...

随机推荐

  1. sqlmap--tamper使用技巧

    apostrophemask.py 适用数据库:ALL 作用:将引号替换为utf-8,用于过滤单引号 使用脚本前: tamper("1 AND '1'='1") 使用脚本后: 1A ...

  2. python png图片生成gif

    有时候写代码就是这样别人把代码写好你在后面加一个句号就行了 我很懒不想写成函数,你自己来吧.有注释就不错了 这个依赖一个图像处理库pillow,轮子就是轮他不是车 import imageio imp ...

  3. oo第一单元学习总结

    写在开头: 第一次接触面向对象思想和java语言,在学习以及完成作业的过程经历了一个比较痛苦的过程, 虽然在每次写作业时总是会有一些小小的抱怨,虽然写出的代码还是很差, 但是看到自己有所进步,还是感觉 ...

  4. CODING 助力江苏高速信息实现组织敏捷与研发敏捷,领跑智慧交通新基建

    疫情之下的高速公路管控重任 江苏高速公路信息工程有限公司(以下简称:江苏高速信息)成立于 2002 年,是江苏交通控股旗下,专业从事高速公路领域机电系统集成.智能交通软硬件研发.大数据分析运营的高新技 ...

  5. 晶振在电路设计时关于负载电容CL大小取值特别需要注意什么?

    在无源晶体的设计中,经常遇到负载电容CL的大小取值.晶振设计与精度的提高.KHz无源晶振的停止.音叉晶体谐振器的精度漂移以及精度和无源晶振在高温下的精度是否等于低温的精度烦忧的问题等. 无源晶体振荡器 ...

  6. 零基础入门非常好的C语言基础资料

    C语言程序的结构认识 用一个简单的c程序例子,介绍c语言的基本构成.格式.以及良好的书写风格,使小伙伴对c语言有个初步认识. 例1:计算两个整数之和的c程序: #include main() { in ...

  7. 链表分割 牛客网 程序员面试金典 C++ Python

    链表分割 牛客网 程序员面试金典 C++ Python 题目描述 编写代码,以给定值x为基准将链表分割成两部分,所有小于x的结点排在大于或等于x的结点之前 给定一个链表的头指针 ListNode* p ...

  8. PE头详细分析

    目录 PE头详细分析 0x00 前言 0x01 PE文件介绍 0x02 PE头详细分析 DOS头解析 NT头解析 标准PE头解析 可选PE头解析 可选PE头结构 基址 代码段地址 数据段地址 OEP程 ...

  9. Mybatis的分页插件com.github.pagehelper

    1. 需要引入PageHelper的jar包 如果没有使用maven,那直接把jar包导入到lib文件夹下即可,这个PageHelper插件在github上有开源, 地址为:https://githu ...

  10. clnt_create: RPC: Port mapper failure - Unable to receive: errno 111 (Connection refused)

    clnt_create: RPC: Port mapper failure - Unable to receive: errno 111 (Connection refused) 关闭防火墙,可以连, ...