题目链接:http://codeforces.com/problemset/problem/1114/F

题意:序列$a$,有两种操作,1 区间里的数同时乘上$x$ 2 求区间的积的欧拉函数

线段树好题。

思路:最直观的思路是,线段树每个节点维护的是一个数组,表示这个数每个素因子及出现的次数,欧拉函数值用矩阵快速幂求解即可。但是这样空间不大够,而且复杂度多个常数,因此不大行。

发现300以内的素数刚好有62个,那么可以用一个long long的二进制数来表示这个数有那些素因子出现,在维护一下区间积,欧拉函数值可以用公式

$\varphi \left( n\right) =n\cdot \dfrac {\prod \left( p_{i}-1\right) }{\prod p_{i}}$

lazy_tag有两个,一个是异或,一个是乘积。我刚开始没用异或,准备直接用乘积来得到异或值,但是因为会取模,所以乘积标记不能用来得到位上的值。

#include <bits/stdc++.h>
#define lp p << 1
#define rp p << 1 | 1
#define ll long long
using namespace std; template<typename T>
inline void read(T &x) {
x = ; T f = ; char ch = getchar();
while (ch < '' || ch > '') { if (ch == '-') f = -; ch = getchar(); }
while (ch >= '' && ch <= '') { x = x * + ch - ; ch = getchar() ;}
x *= f;
} const ll MOD = 1e9 + ;
const int N = 4e5 + ;
int prime[], prin, a[N], n;
ll inv[];
bool vis[]; ll qp(ll a, ll b) {
ll res = ;
while (b) {
if (b & ) res = res * a % MOD;
a = a * a % MOD;
b >>= ;
}
return res;
} inline ll getbin(ll x) {
ll res = ;
for (int i = ; i < prin; i++)
if (x % prime[i] == ) res |= (1LL << i);
return res;
} struct SEG {
ll appear[N << ], num[N << ], lazy[N << ], lazy_bin[N << ];
void pushup(int p) {
appear[p] |= (appear[lp] | appear[rp]);
num[p] = num[lp] * num[rp] % MOD;
}
void pushdown(int p, int llen, int rlen) {
lazy[lp] = lazy[lp] * lazy[p] % MOD;
lazy[rp] = lazy[rp] * lazy[p] % MOD;
lazy_bin[lp] |= lazy_bin[p]; lazy_bin[rp] |= lazy_bin[p];
appear[lp] |= lazy_bin[lp];
appear[rp] |= lazy_bin[rp];
num[lp] = num[lp] * qp(lazy[p], llen) % MOD;
num[rp] = num[rp] * qp(lazy[p], rlen) % MOD;
lazy[p] = ;
lazy_bin[p] = ;
}
void build(int p, int l, int r) {
appear[p] = num[p] = lazy_bin[p] = ;
lazy[p] = ;
if (l == r) {
num[p] = a[l];
appear[p] = getbin(a[l]);
return;
}
int mid = l + r >> ;
build(lp, l, mid);
build(rp, mid + , r);
pushup(p);
}
void update(int p, int l, int r, int x, int y, ll v, ll bin) {
if (x <= l && r <= y) {
lazy_bin[p] |= bin;
appear[p] |= bin;
lazy[p] = lazy[p] * v % MOD;
num[p] = num[p] * qp(v, r - l + ) % MOD;
return;
}
int mid = l + r >> ;
pushdown(p, mid - l + , r - mid);
if (x <= mid) update(lp, l, mid, x, y, v, bin);
if (y > mid) update(rp, mid + , r, x, y, v, bin);
pushup(p);
}
void query(int p, int l, int r, int x, int y, ll &v, ll &bin) {
if (x <= l && r <= y) {
v = v * num[p] % MOD;
bin |= appear[p];
return;
}
int mid = l + r >> ;
pushdown(p, mid - l + , r - mid);
if (x <= mid) query(lp, l, mid, x, y, v, bin);
if (y > mid) query(rp, mid + , r, x, y, v, bin);
}
} seg; char s[]; int main() {
//freopen("in.txt", "r", stdin);
for (int i = ; i < ; i++) {
if (!vis[i]) prime[prin++] = i;
for (int j = ; j < prin && i * prime[j] < ; j++) {
vis[i * prime[j]] = ;
if (i % prime[j] == ) break;
}
}
inv[] = ;
for (int i = ; i < ; i++) inv[i] = (MOD - MOD / i) * inv[MOD % i] % MOD;
read(n);
int q; read(q);
for (int i = ; i <= n; i++) read(a[i]);
seg.build(, , n);
while (q--) {
scanf("%s", s);
if (s[] == 'T') {
int l, r;
read(l); read(r);
ll v = , bin = ;
seg.query(, , n, l, r, v, bin);
for (int i = ; i < prin; i++) {
if (bin >> i & ) v = v * (prime[i] - ) % MOD * inv[prime[i]] % MOD;
}
printf("%lld\n", v);
} else {
int l, r, w;
read(l); read(r); read(w);
seg.update(, , n, l, r, w, getbin(w));
}
}
return ;
}

Codeforces1114F Please, another Queries on Array?的更多相关文章

  1. Codeforces 1114F Please, another Queries on Array? 线段树

    Please, another Queries on Array? 利用欧拉函数的计算方法, 用线段树搞一搞就好啦. #include<bits/stdc++.h> #define LL ...

  2. CF1114F Please, another Queries on Array?

    CF1114F Please, another Queries on Array? 考虑用线段树维护取模后的区间积和真正的区间积所含有的质因子. 每次询问查得这两个值后,一乘一除,即可算出该区间积的欧 ...

  3. [Codeforces 266E]More Queries to Array...(线段树+二项式定理)

    [Codeforces 266E]More Queries to Array...(线段树+二项式定理) 题面 维护一个长度为\(n\)的序列\(a\),\(m\)个操作 区间赋值为\(x\) 查询\ ...

  4. 暑假集训单切赛第一场 CF 266E More Queries to Array(线段树+二项式展开式)

    比赛时,第二题就是做的这个,当时果断没仔细考虑,直接用线段树暴力求.结果易想而知,超时了. 比赛后搜了搜题解,恍然大悟. 思路:显然用线段树,但是由于每次查询都会有变,所以不可能存储题目中的式子.   ...

  5. [Codeforces266E]More Queries to Array...——线段树

    题目链接: Codeforces266E 题目大意:给出一个序列$a$,要求完成$Q$次操作,操作分为两种:1.$l,r,x$,将$[l,r]$的数都变为$x$.2.$l,r,k$,求$\sum\li ...

  6. Codeforces 1114F Please, another Queries on Array? [线段树,欧拉函数]

    Codeforces 洛谷:咕咕咕 CF少有的大数据结构题. 思路 考虑一些欧拉函数的性质: \[ \varphi(p)=p-1\\ \varphi(p^k)=p^{k-1}\times (p-1)= ...

  7. 【Codeforces 1114F】Please, another Queries on Array?

    Codeforces 1114 F 题意:给你一个序列\(a_{1\dots n}\),以及\(q\)次查询,每次查询有两种格式: TOTIENT \(l\) \(r\):求出\(\phi(\Pi_{ ...

  8. CF1114F Please, another Queries on Array?(线段树,数论,欧拉函数,状态压缩)

    这题我在考场上也是想出了正解的……但是没调出来. 题目链接:CF原网 题目大意:给一个长度为 $n$ 的序列 $a$,$q$ 个操作:区间乘 $x$,求区间乘积的欧拉函数模 $10^9+7$ 的值. ...

  9. Please, another Queries on Array? CodeForces - 1114F (线段树,欧拉函数)

    这题刚开始看成求区间$\phi$和了........先说一下区间和的做法吧...... 就是说将题目的操作2改为求$(\sum\limits_{i=l}^{r}\phi(a[i]))\%P$ 首先要知 ...

随机推荐

  1. 17 SpringMVC response响应

    1.Model.ModelMap和ModelAndView的使用详解 Spring-MVC在请求处理方法可出现和返回的参数类型中,最重要就是Model和ModelAndView了,对于MVC框架,控制 ...

  2. SQL Server中的GAM页和SGAM页

    简介 我们已经知道SQL Server IO最小的单位是页,连续的8个页是一个区.SQL Server需要一种方式来知道其所管辖的数据库中的空间使用情况,这就是GAM页和SGAM页. Global A ...

  3. 测试代码的练习——python编程从入门到实践

    11-1 城市和国家:编写一个函数,它接受两个形参:一个城市名和一个国家名.这个函数返回一个格式为City,Country的字符串,如Santiago,Chile.这个函数存储在一个名为city_fu ...

  4. 54 容器(九)——HashSet

    HashSet的特点: 无序,不可重复. HashSet实现自Set,而Set继承自Collection,在日常使用中,我们都是以Set引用指向HashSet对象的方式. 所以,Set中的方法是我们主 ...

  5. Mysql】Mysql中CURRENT_TIMESTAMP,CURRENT_DATE,CURRENT_TIME,now(),sysdate()各项值的区别

    CURRENT_TIMESTAMP,CURRENT_DATE,CURRENT_TIME,now(),sysdate()各项值的区别,我们可以通过在终端下,查看结果就能知道: SELECT CURREN ...

  6. 【1】【leetcode-72 动态规划】 编辑距离

    (没思路,很典型,重要) 给定两个单词 word1 和 word2,计算出将 word1 转换成 word2 所使用的最少操作数 . 你可以对一个单词进行如下三种操作: 插入一个字符 删除一个字符 替 ...

  7. C#直接调用.mdf文件

    一般情况下,.mdf文件都是作为MSSQL的数据库文件,只有在安装了Microsoft SQL Server才能实现调用. 事实上,除此之外,也可以直接调用.mdf文件,而无需安装Microsoft ...

  8. Idea创建一个SpringBoot工程

    1.打开Idea,点击新建工程 File—New—Project 2.点击下一步后可能会很一直在请求,或者直接报如下错误, 解决办法:直接点OK后再点Previous返回上一步,继续重新Next 3. ...

  9. 常用模块 - configparse模块

    一.简介 configparser模块在Python中是用来读取配置文件的,配置文件的格式跟windows下的ini配置文件相似,可以包含一个或多个节点(section),每个节可以有多个参数(键=值 ...

  10. css-博客样式初体验

    css学习一周后,写了个基础博客样式. 样式是出来了,但是在写的过程中感觉css写的杂乱无章,可能是写的太少了吧,条例不是很清除,只是在写的过程 中一个点一个点的套,感觉样式出来即可,没有做到由全局出 ...