首页 > 其他 > 详细

洛谷 P3373 【模板】线段树 2

时间:2019-08-03 21:50:33      阅读:95      评论:0      收藏:0      [点我收藏+]

题目传送门

本题相对于模板1多了乘法,但是代码里面加入了要考虑优先级的因素,所以并不是很好写.

AC代码:

技术分享图片
  1 #include<cstdio>
  2 #include<iostream>
  3 
  4 using namespace std;
  5 
  6 int n,m,p;
  7 long long a[100001];
  8 struct kkk {
  9     long long v,mul,add;
 10 
 11 }e[400005]; 
 12 
 13 inline void build(int bh,int l,int r) {
 14     e[bh].mul = 1;
 15     e[bh].add = 0;
 16     if(l == r) {
 17         e[bh].v = a[l] % p;
 18         return ;    
 19     }
 20     int mid = l + r >> 1;
 21     build(bh * 2,l,mid);
 22     build(bh * 2 + 1,mid + 1,r);
 23     e[bh].v = e[bh*2].v + e[bh*2+1].v;
 24 
 25     e[bh].v %= p;
 26     return ;
 27 }
 28 
 29 inline void pushdown(int bh,int l,int r) {
 30     int mid = (l + r) >> 1;
 31     e[bh*2].v = (e[bh*2].v * e[bh].mul + e[bh].add * (mid - l + 1)) % p;
 32     e[bh*2+1].v = (e[bh*2+1].v * e[bh].mul + e[bh].add * (r - mid)) % p;
 33     e[bh*2].mul = (e[bh*2].mul * e[bh].mul) % p;
 34     e[bh*2+1].mul = (e[bh*2+1].mul * e[bh].mul) % p;
 35     e[bh*2].add = (e[bh*2].add * e[bh].mul + e[bh].add) % p;
 36     e[bh*2+1].add = (e[bh*2+1].add * e[bh].mul + e[bh].add) % p;
 37     e[bh].mul = 1;
 38     e[bh].add = 0;
 39     return ;
 40 }
 41 
 42 inline void update_Multiply(int bh,int ll,int rr,int l,int r,long long _v) {
 43     if(r < ll || l > rr)
 44         return ;
 45     if(l <= ll && r >= rr) {
 46         e[bh].v = (e[bh].v * _v) % p;
 47         e[bh].mul = (e[bh].mul * _v) % p;
 48         e[bh].add = (e[bh].add * _v) % p;
 49         return ; 
 50     }    
 51     pushdown(bh,ll,rr);
 52 
 53     int mid = (ll + rr) >> 1;
 54     update_Multiply(bh * 2,ll,mid,l,r,_v);
 55 
 56     update_Multiply(bh * 2 + 1,mid + 1,rr,l,r,_v);
 57     e[bh].v = (e[bh*2].v + e[bh*2+1].v) % p;
 58     return ;
 59 }
 60 
 61 inline void update_Plus(int bh,int ll,int rr,int l,int r,long long _v) {
 62     if(r < ll || rr < l)
 63         return ;
 64     if(l <= ll && r >= rr) { 
 65         e[bh].add = (e[bh].add + _v) % p;
 66         e[bh].v = (e[bh].v + _v * (rr - ll + 1)) % p;
 67         return ;
 68     }
 69     pushdown(bh,ll,rr);
 70 
 71     int mid = (ll + rr) >> 1;
 72     update_Plus(bh * 2,ll,mid,l,r,_v);
 73 
 74     update_Plus(bh * 2 + 1,mid + 1,rr,l,r,_v);
 75     e[bh].v = (e[bh*2].v + e[bh*2+1].v) % p;
 76     return ;
 77 } 
 78 
 79 long long query(int bh,int ll,int rr,int l,int r) {
 80     if(r < ll || l > rr) 
 81         return 0;
 82     if(l <= ll && r >= rr)
 83         return e[bh].v;
 84 
 85     pushdown(bh,ll,rr);
 86 
 87     int mid = (ll + rr) >> 1;
 88     return (query(bh * 2,ll,mid,l,r) + query(bh * 2 + 1,mid + 1,rr,l,r)) % p;
 89 }
 90 
 91 int main()
 92 {
 93     scanf("%d%d%d",&n,&m,&p);
 94 
 95     for(int i = 1;i <= n; i++)
 96         scanf("%lld",&a[i]);
 97 
 98     build(1,1,n);
 99 
100     while(m--) {
101         int u,x,y;
102         long long k;
103         scanf("%d",&u);
104 
105         if(u == 1) {
106             scanf("%d%d%lld",&x,&y,&k);
107 
108             update_Multiply(1,1,n,x,y,k);
109         }
110         if(u == 2) {
111             scanf("%d%d%lld",&x,&y,&k);
112 
113             update_Plus(1,1,n,x,y,k);
114         }
115         if(u == 3) {
116             scanf("%d%d",&x,&y);
117 
118             printf("%lld\n",query(1,1,n,x,y) % p);
119         }
120     }
121     return 0;
122 }
线段树乘法

 

洛谷 P3373 【模板】线段树 2

原文:https://www.cnblogs.com/lipeiyi520/p/11296301.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!