大意: 给定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 (数学,线段树)相关推荐

  1. Codeforces 786B Legacy (线段树优化建图)

    Codeforces 786B Legacy (线段树优化建图) 题意:\(n\)个点,有\(3\)种连边操作:1.将\(u\)指向\(v\):2.将\(v\)指向编号在区间\([l,r]\)的点:3 ...

  2. Sereja and Brackets CodeForces - 380C (线段树+分治思路)

    Sereja and Brackets 题目链接: CodeForces - 380C Sereja has a bracket sequence s1, s2, ..., *s**n, or, in ...

  3. Distinct Characters Queries CodeForces - 1234D(线段树求区间字母种类数)

    You are given a string ss consisting of lowercase Latin letters and qq queries for this string. Reca ...

  4. codeforces 650D. Zip-line 线段树

    题目链接 题目的意思很简单, 就是给你n个数, m个询问, 每次询问修改某一个位置的值, 然后问你修改完之后数列的lis是多少. 询问独立. 对于原数列, 我们将它离散化, 令dp1[i]为以i为结尾 ...

  5. CodeForces - 787D - Legacy(线段树优化建图+最短路)

    题目链接:点击查看 题目大意:给出 nnn 个点和 mmm 条边,现在需要求从 ststst 开始到所有点的最短路是多少,mmm 条边的给出方式如下: 1uvw1 \ u \ v \ w1 u v w ...

  6. CodeForces - 487B Strip(线段树+dp+二分)

    题目链接:点击查看 题目大意:给出一个长度为 n 的序列,现在要求分成尽可能少的子段,且每个子段需要满足: 最大值与最小值的差值小于等于 s 子段长度大于等于 l 题目分析:dp[ i ] 代表的是前 ...

  7. CodeForces - 1354D Multiset(线段树/二分)

    题目链接:点击查看 题目大意:规定在一个 multiset 中初始时有 n 个元素,随后有 m 次操作,每次操作给出一个 num: num > 0 时:向 multiset 中添加 num nu ...

  8. CodeForces - 1326E Bombs(线段树+思维)

    题目链接:点击查看 题目大意:给出一个 n 的排列记为 p[ i ] ,现在有一个初始时为空的集合A,对于每个 i 遍历 1 ~ n ,每次的操作如下: 向集合中添加 p[ i ] 如果位置 i 有炸 ...

  9. 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 ...

最新文章

  1. 技术图文:C#语言中的泛型 I
  2. Python 列表List的定义及操作
  3. js RegExp正则表达式常见用例
  4. LeetCode 1775. 通过最少操作次数使数组的和相等(贪心+双指针)
  5. 对象不支持属性或方法dbzz.html,JavaScript 中 setTimeout()的用法 ZZ
  6. akka actor java_现代化的Java(三)——从Hello Akka说起
  7. matlab2c使用c++实现matlab函数系列教程-circshift函数
  8. android开机启动shell脚本
  9. IRP请求的完成与返回
  10. MySQL笔记4——SQL去重/笛卡尔积现象
  11. 百胜也要做外卖?市场会重新回到三足鼎立吗
  12. uni-app 使用API中的uni.chooseImage 上传照片以及uni.previewImage图片预览(身份证照片为例)
  13. 未来10年,软件开发技术的8个发展趋势
  14. 探秘C++之回炉重造
  15. 网易云获取带有时间轴的歌词
  16. [转]我的FLASH情结2010——浅谈FLASH WEB GAME与创业(下)
  17. 怎么提升淘宝网店的转化率
  18. 海思HI3751HiDPTAndroidV200R001 UNF 接口版本差异说明
  19. October 2009
  20. 印尼央行发移动支付“新规”,这家中国公司成为“唯一”彩蛋

热门文章

  1. 滴滴为什么接不到长途单?
  2. 路由器太远手机接收不到信号怎么办
  3. 连昌宫词 [唐] 元稹
  4. 一公顷等于多少平方米
  5. 如何评价NVIDIA RTX 2080 Ti显卡?
  6. go使用makefile
  7. anaconda安装pytorch1.7.1和torchvision0.8.2的方法,亲测可用
  8. 多文件结构和编译预处理命令
  9. make: 'pcs.o' is up to date.问题解决
  10. azure云数据库_Azure SQL数据库的安全注意事项