Sasha and a Very Easy Test CodeForces - 1109E (数学,线段树)
大意: 给定n元素序列, q个操作: (1)区间乘 (2)单点除(保证整除) (3)区间求和对m取模
要求回答所有操作(3)的结果
主要是除法难办, 假设单点除$x$, $x$中与$m$互素的素因子可以直接欧拉求逆, 其余因子维护一个向量即可.
这种沙茶题结果各种细节出错改了一个多小时......太菜了
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <math.h>
#include <set>
#include <map>
#include <queue>
#include <string>
#include <string.h>
#define REP(i,a,n) for(int i=a;i<=n;++i)
#define PER(i,a,n) for(int i=n;i>=a;--i)
#define hr putchar(10)
#define pb push_back
#define lc (o<<1)
#define rc (lc|1)
#define mid ((l+r)>>1)
#define ls lc,l,mid
#define rs rc,mid+1,r
#define x first
#define y second
#define io std::ios::sync_with_stdio(false)
#define endl '\n'
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int P = 1e9+7, INF = 0x3f3f3f3f;
ll gcd(ll a,ll b) {return b?gcd(b,a%b):a;}
ll inv(ll x){return x<=1?1:inv(P%x)*(P-P/x)%P;}
//headconst int N = 1e5+10;int n, m, q, sz, Phi;
vector<int> A;int phi(int x) {int s = x, mx = sqrt(x+0.5);REP(i,2,mx) if (x%i==0) {s = s/i*(i-1);A.pb(i);while (x%i==0) x/=i;}if (x>1) A.pb(x),s=s/x*(x-1);sz = A.size();return s;
}ll qpow(ll a,ll n) {ll r=1%m;for (a%=m;n;a=a*a%m,n>>=1)if(n&1)r=r*a%m;return r;}int sum[N<<2], rtag[N<<2], tag[N<<2], res[N<<2];
int c[N<<2][10], tagc[N<<2][10];
int ans, ql, qr, qv[10];void pd(int o) {if (tag[o]!=1) {tag[lc] = (ll)tag[lc]*tag[o]%m;tag[rc] = (ll)tag[rc]*tag[o]%m;sum[lc] = (ll)sum[lc]*tag[o]%m;sum[rc] = (ll)sum[rc]*tag[o]%m;tag[o] = 1;}if (rtag[o]!=1) {res[lc] = (ll)res[lc]*rtag[o]%m;res[rc] = (ll)res[rc]*rtag[o]%m;rtag[lc] = (ll)rtag[lc]*rtag[o]%m;rtag[rc] = (ll)rtag[rc]*rtag[o]%m;rtag[o] = 1;}REP(i,0,sz-1) { c[lc][i]+=tagc[o][i],c[rc][i]+=tagc[o][i];tagc[lc][i]+=tagc[o][i],tagc[rc][i]+=tagc[o][i];tagc[o][i]=0;}
}void pu(int o) {sum[o]=(sum[rc]+sum[lc])%m;
}void build(int o, int l, int r) {sum[o]=res[o]=tag[o]=rtag[o]=1;if (l==r) {int t;scanf("%d", &t);sum[o] = t%m;REP(i,0,sz-1) {while (t%A[i]==0) t/=A[i],++c[o][i];}res[o] = t%m;return;}build(ls),build(rs);pu(o);
}void mul(int o, int l, int r, int x, int R) {if (ql<=l&&r<=qr) {sum[o] = (ll)sum[o]*x%m;tag[o] = (ll)tag[o]*x%m;res[o] = (ll)res[o]*R%m;rtag[o] = (ll)rtag[o]*R%m;REP(i,0,sz-1) c[o][i]+=qv[i],tagc[o][i]+=qv[i];return;}pd(o);if (mid>=ql) mul(ls,x,R);if (mid<qr) mul(rs,x,R);pu(o);
}
void div(int o, int l, int r, int x, int v) {if (l==r) {REP(i,0,sz-1) {while (v%A[i]==0) v/=A[i],--c[o][i];}res[o] = (ll)res[o]*qpow(v,Phi-1)%m;sum[o] = res[o];REP(i,0,sz-1) sum[o]=(ll)sum[o]*qpow(A[i],c[o][i])%m;return;}pd(o);if (mid>=x) div(ls,x,v);else div(rs,x,v);pu(o);
}
void query(int o, int l, int r, int ql, int qr) {if (ql<=l&&r<=qr) return (ans+=sum[o])%=m,void();pd(o);if (mid>=ql) query(ls,ql,qr);if (mid<qr) query(rs,ql,qr);
}int main() {scanf("%d%d", &n, &m);Phi = phi(m);build(1,1,n);scanf("%d", &q);while (q--) {int op, x, p;scanf("%d", &op);if (op==1) {scanf("%d%d%d",&ql,&qr,&x);int t = x;REP(i,0,sz-1) { qv[i] = 0;while (t%A[i]==0) t/=A[i],++qv[i];}mul(1,1,n,x,t);} else if (op==2) {scanf("%d%d",&p,&x);div(1,1,n,p,x);} else {scanf("%d%d",&ql,&qr);ans = 0, query(1,1,n,ql,qr);printf("%d\n", ans);}}
}
转载于:https://www.cnblogs.com/uid001/p/10507346.html
Sasha and a Very Easy Test CodeForces - 1109E (数学,线段树)相关推荐
- Codeforces 786B Legacy (线段树优化建图)
Codeforces 786B Legacy (线段树优化建图) 题意:\(n\)个点,有\(3\)种连边操作:1.将\(u\)指向\(v\):2.将\(v\)指向编号在区间\([l,r]\)的点:3 ...
- Sereja and Brackets CodeForces - 380C (线段树+分治思路)
Sereja and Brackets 题目链接: CodeForces - 380C Sereja has a bracket sequence s1, s2, ..., *s**n, or, in ...
- Distinct Characters Queries CodeForces - 1234D(线段树求区间字母种类数)
You are given a string ss consisting of lowercase Latin letters and qq queries for this string. Reca ...
- codeforces 650D. Zip-line 线段树
题目链接 题目的意思很简单, 就是给你n个数, m个询问, 每次询问修改某一个位置的值, 然后问你修改完之后数列的lis是多少. 询问独立. 对于原数列, 我们将它离散化, 令dp1[i]为以i为结尾 ...
- CodeForces - 787D - Legacy(线段树优化建图+最短路)
题目链接:点击查看 题目大意:给出 nnn 个点和 mmm 条边,现在需要求从 ststst 开始到所有点的最短路是多少,mmm 条边的给出方式如下: 1uvw1 \ u \ v \ w1 u v w ...
- CodeForces - 487B Strip(线段树+dp+二分)
题目链接:点击查看 题目大意:给出一个长度为 n 的序列,现在要求分成尽可能少的子段,且每个子段需要满足: 最大值与最小值的差值小于等于 s 子段长度大于等于 l 题目分析:dp[ i ] 代表的是前 ...
- CodeForces - 1354D Multiset(线段树/二分)
题目链接:点击查看 题目大意:规定在一个 multiset 中初始时有 n 个元素,随后有 m 次操作,每次操作给出一个 num: num > 0 时:向 multiset 中添加 num nu ...
- CodeForces - 1326E Bombs(线段树+思维)
题目链接:点击查看 题目大意:给出一个 n 的排列记为 p[ i ] ,现在有一个初始时为空的集合A,对于每个 i 遍历 1 ~ n ,每次的操作如下: 向集合中添加 p[ i ] 如果位置 i 有炸 ...
- New Year and Old Subsequence CodeForces - 750E(线段树+矩阵dp)2019南昌icpc网络赛Hello 2019
A string t is called nice if a string "2017" occurs in t as a subsequence but a string &qu ...
最新文章
- 技术图文:C#语言中的泛型 I
- Python 列表List的定义及操作
- js RegExp正则表达式常见用例
- LeetCode 1775. 通过最少操作次数使数组的和相等(贪心+双指针)
- 对象不支持属性或方法dbzz.html,JavaScript 中 setTimeout()的用法 ZZ
- akka actor java_现代化的Java(三)——从Hello Akka说起
- matlab2c使用c++实现matlab函数系列教程-circshift函数
- android开机启动shell脚本
- IRP请求的完成与返回
- MySQL笔记4——SQL去重/笛卡尔积现象
- 百胜也要做外卖?市场会重新回到三足鼎立吗
- uni-app 使用API中的uni.chooseImage 上传照片以及uni.previewImage图片预览(身份证照片为例)
- 未来10年,软件开发技术的8个发展趋势
- 探秘C++之回炉重造
- 网易云获取带有时间轴的歌词
- [转]我的FLASH情结2010——浅谈FLASH WEB GAME与创业(下)
- 怎么提升淘宝网店的转化率
- 海思HI3751HiDPTAndroidV200R001 UNF 接口版本差异说明
- October 2009
- 印尼央行发移动支付“新规”,这家中国公司成为“唯一”彩蛋