花火之声不闻于耳花火之声不闻于耳花火之声不闻于耳




正解部分\color{red}{正解部分}正解部分

现在要求的是 φ(∏i=LRai)=∏i=LRai×∏pj−1pj\varphi \left( \prod_{i=L}^R a_i \right) = \prod_{i=L}^R a_i \times \prod \frac{p_j-1}{p_j}φ(∏i=LR​ai​)=∏i=LR​ai​×∏pj​pj​−1​,

答案只与 aia_iai​ 的值 和 其包含的质数有关, 而题目中涉及到的质数不超过 626262 个 .

于是使用两颗线段树, 一颗记录乘积的信息, 一颗记录相关质数出现的信息,
其中质数出现的信息可以以二进制形式存储到 longlonglong\ longlong long 中 .


实现部分\color{red}{实现部分}实现部分

  • 注意线段树乘法懒标记初值为 111 .
  • <<<<<< 不要写成 <<< .
  • 1<<x1<<x1<<x 应该为 1ll<<x1ll<<x1ll<<x.
#include<bits/stdc++.h>
#define reg register
typedef long long ll;int read(){char c;int s = 0, flag = 1;while((c=getchar()) && !isdigit(c))if(c == '-'){ flag = -1, c = getchar(); break ; }while(isdigit(c)) s = s*10 + c-'0', c = getchar();return s * flag;
}const int maxn = 1e6 + 5;
const int mod = 998244353;int N;
int M;
int p_cnt;
int A[maxn];
int pos[maxn];
int from[maxn];
int prime[maxn];
int p_inv[maxn];bool vis[maxn];ll State;int Ksm(int a, int b){ int s=1; while(b){ if(b&1) s=1ll*s*a%mod; a=1ll*a*a%mod; b>>=1; } return s; }void sieve(){for(reg int i = 2; i <= 300; i ++){if(!vis[i]) prime[++ p_cnt] = i, p_inv[p_cnt] = (1ll*i-1)*Ksm(i, mod-2)%mod, from[i] = i, pos[i] = p_cnt;for(reg int j = 1; j <= p_cnt && prime[j]*i <= 300; j ++){ vis[prime[j]*i] = 1; from[prime[j]*i] = prime[j]; if(i % prime[j] == 0) break ;}}
}ll Calc_zt(int x){ ll res=0; while(x > 1){ res |= (1ll<<pos[from[x]]-1); x /= from[x]; } return res; }struct Segment_Tree{struct Node{ int l, r, sum, tag_1; ll zt, tag_2; } T[maxn << 2];void Build(int k, int l, int r){T[k].l = l, T[k].r = r, T[k].tag_1 = 1, T[k].tag_2 = 0;if(l == r){ T[k].sum = A[l]; T[k].zt = Calc_zt(A[l]); return ; }int mid = l+r >> 1;Build(k<<1, l, mid), Build(k<<1|1, mid+1, r);T[k].sum = 1ll*T[k<<1].sum * T[k<<1|1].sum % mod;T[k].zt = T[k<<1].zt | T[k<<1|1].zt;}void Push_down(int k){int lt = k<<1, rt = k<<1|1, len = T[k].r-T[k].l+1;T[k].sum = 1ll*T[k].sum*Ksm(T[k].tag_1, len)%mod, T[k].zt |= T[k].tag_2; T[lt].tag_1 = 1ll*T[lt].tag_1*T[k].tag_1 % mod;T[rt].tag_1 = 1ll*T[rt].tag_1*T[k].tag_1 % mod;T[lt].zt |= T[k].tag_2, T[lt].tag_2 |= T[k].tag_2;T[rt].zt |= T[k].tag_2, T[rt].tag_2 |= T[k].tag_2;T[k].tag_1 = 1, T[k].tag_2 = 0;}void Modify(int k, const int &ql, const int &qr, const int &x, const ll &st){if(T[k].tag_1 != 1 || T[k].tag_2) Push_down(k);int l = T[k].l, r = T[k].r;if(ql > r || qr < l) return ;if(ql <= l && r <= qr){T[k].tag_1 = 1ll*T[k].tag_1*x % mod;T[k].tag_2 |= st, T[k].zt |= st;Push_down(k);return ;}int mid = l+r >> 1;Modify(k<<1, ql, qr, x, st);Modify(k<<1|1, ql, qr, x, st);T[k].sum = 1ll*T[k<<1].sum*T[k<<1|1].sum % mod;T[k].zt = T[k<<1].zt | T[k<<1|1].zt;}int Query(int k, const int &ql, const int &qr){if(T[k].tag_1 != 1 || T[k].tag_2) Push_down(k);int l = T[k].l, r = T[k].r;if(ql > r || qr < l) return 1;if(ql <= l && r <= qr){ State |= T[k].zt; return T[k].sum; }int mid = l+r >> 1, res = 1;res = 1ll*res*Query(k<<1, ql, qr) % mod;res = 1ll*res*Query(k<<1|1, ql, qr) % mod;return res;}} seg_t;int main(){freopen("hanabi.in", "r", stdin);freopen("hanabi.out", "w", stdout);sieve(); N = read(), M = read();for(reg int i = 1; i <= N; i ++) A[i] = read(); seg_t.Build(1, 1, N);/*int res = 0;res = seg_t.Query(1, 233, 90000);std::cout << res << std::endl;for(reg int j = 1; j <= p_cnt; j ++) if(State & (1ll<<j-1)) res = 1ll*res*p_inv[j]%mod;std::cout << State << std::endl;*/for(reg int i = 1; i <= M; i ++){int op = read(), L = read(), R = read();if(op == 1){ int x = read();seg_t.Modify(1, L, R, x, Calc_zt(x)); } else{State = 0;int res = seg_t.Query(1, L, R);for(reg int j = 1; j <= p_cnt; j ++) if(State & (1ll<<j-1)) res = 1ll*res*p_inv[j]%mod;printf("%d\n", res);}}return 0;
}

花火之声不闻于耳 [线段树]相关推荐

  1. uoj#388. 【UNR #3】配对树(线段树合并)

    传送门 先考虑一个贪心,对于一条边来说,如果当前这个序列中在它的子树中的元素个数为奇数个,那么这条边就会被一组匹配经过,否则就不会 考虑反证法,如果在这条边两边的元素个数都是偶数,那么至少有两组匹配经 ...

  2. 3682: Phorni 后缀平衡树 线段树

    国际惯例的题面: 考虑如果没有强制在线我们能怎么水掉这个题,先构造出字符串,各种方法求一下后缀数组,然后线段树维护区间rank最小的位置即可. 然而他要求强制在线,支持插入后缀,并比较后缀大小(求ra ...

  3. 模板三连击:树状数组+线段树+主席树

    没事儿干,复习模板...... 1.树状数组 本来不想写这个的,但是反正就几分钟就打完了,所以就写了,水AC数. 洛谷 P3374 [模板]树状数组 1 1 #include<cstdio> ...

  4. 【GDOI2016】疯狂动物城(树链剖分+可持久化线段树)

    码农题- 调了我三个晚上- 看来我的代码能力还是太弱了- 首先我们不难发现在u到v这条链的答案为∑i=1n(n−i)(n−i+1)ai2\sum_{i=1}^n\frac{(n-i)(n-i+1)a_ ...

  5. nyoj 1217 GLaDOS的耳机(线段树,开两个标记数组维护)

    1217-GLaDOS的耳机 内存限制:64MB时间限制:3000msSpecial Judge: No accepted:8submit:40 题目描述: GLaDOS是个耳机控.对于他来说,已经不 ...

  6. 【贪心 / 线段树模拟费用流增广】BZOJ4977 [Lydsy八月月赛] 跳伞求生

    [题目] 原题地址 有nn个队友和mm个敌人,每个队友有一个攻击力aia_i,每个敌人有攻击力bib_i和价值cic_i.你可以选择若干个队友,每个队友ii分别去怼一个敌人jj,当ai>bja_ ...

  7. 二逼平衡树——树套树(线段树套Splay平衡树)

    题面 Bzoj3196 解析 线段树和Splay两棵树套在一起,常数直逼inf,但最终侥幸过了 思路还是比较简单, 在原数组维护一个下标线段树,再在每一个线段树节点,维护一个对应区间的权值Splay. ...

  8. 线段树——HDU - 1698

    题目含义 就是初始化一堆数为1 可以经过操作把一个区间的数都改变 并求这堆数的总大小 题目分析 有一个 #include<iostream> #include<stdio.h> ...

  9. BZOJ.1558.[JSOI2009]等差数列(线段树 差分)

    BZOJ 洛谷 首先可以把原序列\(A_i\)转化成差分序列\(B_i\)去做. 这样对于区间加一个等差数列\((l,r,a_0,d)\),就可以转化为\(B_{l-1}\)+=\(a_0\),\(B ...

最新文章

  1. Domino设置多台转发主机地址
  2. python类中方法的执行顺序-python – 新式类中的方法解析顺序(MRO)?
  3. CrowdRec:众包环境中,基于信任感知的工人推荐
  4. CV之IS:计算机视觉之图像分割(Image Segmentation)算法的挑战任务、算法演化、目标检测和图像分割(语义分割/实例分割/全景分割)的对比
  5. 充一次电使用一年的手机_电动自行车使用充电桩充不满电?原因终于找到了!...
  6. Java迭代器中的next()方法
  7. Linux:分享50个实用的基础命令,欢迎收藏!
  8. 数据库 事务隔离级别之可重复读
  9. 关于JDK中的集合总结(二)
  10. IDEA集成MAVEN 报错
  11. 初探Java8中的HashMap(转)
  12. Linux文件系统(六)---三大缓冲区之 目录缓冲区dcache
  13. 如何在康佳电视上看音乐MV
  14. Spring @scheduled注解周期性执行超时任务对任务调度的影响分析
  15. vertica基本操作
  16. 修改python终端不能打开方法解决
  17. ubuntu下网易云音乐无法打开
  18. 深圳神牛python培训_请教神牛_字符串hash
  19. 一、ECMAScript 6 简介
  20. windows模拟微信小程序_【原创】PC微信小程序包解密工具C#版无需root或模拟器

热门文章

  1. 赢得值系列2:赢得值理论的关键参数
  2. Flashplayer11 And AIR3游戏应用介绍视频
  3. 约瑟夫环 有15个人围成一圈,按顺序淘汰
  4. 【排队助手】投屏模式-使用指南
  5. 如何用计算机设计班牌,班牌设计
  6. 计算机主机的光驱怎么打开,笔记本电脑光驱,教您笔记本光驱怎么打开
  7. Beats:为 Filebeat 配置 inputs
  8. Android类似IOS的果冻效果
  9. python+opencv代码给证件照换底色(别再用PS啦)
  10. BI神器Power Query(4)-- PQ导入动态名称定义的表格