[模板]线段树2-线段树
Posted wangyifan124
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[模板]线段树2-线段树相关的知识,希望对你有一定的参考价值。
真的是这题有毒,坑坑坑坑坑坑!!!
但还是写出来了~~~
#include<bits/stdc++.h> #define ll long long using namespace std; const int maxn = 1e6+5; struct segment_tree{ ll l,r,sum,add,mul; }tree[maxn<<2]; ll Mod; ll n,m; ll num; inline void pushup(ll root){ tree[root].sum = (tree[root<<1].sum+tree[root<<1|1].sum)%Mod; } inline void pushdown(ll root){ tree[root<<1].add = (tree[root].add+tree[root<<1].add*tree[root].mul)%Mod; tree[root<<1|1].add = (tree[root].add+tree[root<<1|1].add*tree[root].mul)%Mod; tree[root<<1].mul = (tree[root<<1].mul*tree[root].mul)%Mod; tree[root<<1|1].mul = (tree[root<<1|1].mul*tree[root].mul)%Mod; tree[root<<1].sum = (tree[root<<1].sum*tree[root].mul+tree[root].add*(tree[root<<1].r-tree[root<<1].l+1))%Mod; tree[root<<1|1].sum = (tree[root<<1|1].sum*tree[root].mul+tree[root].add*(tree[root<<1|1].r-tree[root<<1|1].l+1))%Mod; tree[root].add = 0; tree[root].mul = 1; } inline ll build(ll x,ll L,ll R){ tree[x]=segment_tree{L,R,0,0,1}; if(L == R){ scanf("%lld",&num); return tree[x].sum = num%Mod; } ll mid=(L+R)>>1; return tree[x].sum = (build(x<<1,L,mid)+build(x<<1|1,mid+1,R))%Mod; } inline void update(ll x,ll v,ll op,ll L,ll R){ pushdown(x); if(op == 1 && tree[x].l >= L && tree[x].r <= R){ tree[x].mul = (tree[x].mul*v)%Mod; tree[x].add = (tree[x].add*v)%Mod; tree[x].sum = (tree[x].sum*tree[x].mul)%Mod; return; } if(op == 2 && tree[x].l >= L && tree[x].r <= R){ tree[x].add = (tree[x].add+v)%Mod; tree[x].sum = (tree[x].sum+tree[x].add*(tree[x].r-tree[x].l+1))%Mod; return; } ll mid = (tree[x].l+tree[x].r)>>1; if(L <= mid)update(x<<1,v,op,L,R); if(R > mid)update(x<<1|1,v,op,L,R); pushup(x); } inline ll query(ll x,ll L,ll R){ pushdown(x); if(tree[x].l >= L && tree[x].r <= R)return tree[x].sum%Mod; ll mid = (tree[x].l+tree[x].r)>>1; return ((L <= mid ? query(x<<1,L,R) : 0)+(R > mid ? query(x<<1|1,L,R) : 0))%Mod; } int main(){ scanf("%lld%lld%lld",&n,&m,&Mod); build(1,1,n); for(ll i = 1,op,x,y;i <= m;i++){ ll k; scanf("%lld",&op); if(op != 3)scanf("%lld%lld%lld",&x,&y,&k),update(1,k,op,x,y); if(op == 3)scanf("%lld%lld",&x,&y),printf("%lld ",query(1,x,y)%Mod); } return 0; }
以上是关于[模板]线段树2-线段树的主要内容,如果未能解决你的问题,请参考以下文章