首页 > 其他 > 详细

【bzoj1798】[Ahoi2009]Seq 维护序列seq

时间:2017-02-16 16:50:22      阅读:279      评论:0      收藏:0      [点我收藏+]

题目描述

老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成。 有长为N的数列,不妨设为a1,a2,…,aN 。有如下三种操作形式: (1)把数列中的一段数全部乘一个值; (2)把数列中的一段数全部加一个值; (3)询问数列中的一段数的和,由于答案可能很大,你只需输出这个数模P的值。

输入

第一行两个整数N和P(1≤P≤1000000000)。第二行含有N个非负整数,从左到右依次为a1,a2,…,aN, (0≤ai≤1000000000,1≤i≤N)。第三行有一个整数M,表示操作总数。从第四行开始每行描述一个操作,输入的操作有以下三种形式: 操作1:“1 t g c”(不含双引号)。表示把所有满足t≤i≤g的ai改为ai×c (1≤t≤g≤N,0≤c≤1000000000)。 操作2:“2 t g c”(不含双引号)。表示把所有满足t≤i≤g的ai改为ai+c (1≤t≤g≤N,0≤c≤1000000000)。 操作3:“3 t g”(不含双引号)。询问所有满足t≤i≤g的ai的和模P的值 (1≤t≤g≤N)。 同一行相邻两数之间用一个空格隔开,每行开头和末尾没有多余空格。

输出

对每个操作3,按照它在输入中出现的顺序,依次输出一行一个整数表示询问结果。

样例输入

7 43
1 2 3 4 5 6 7
5
1 2 5 5
3 2 4
2 3 7 9
3 1 3
3 4 7

样例输出

2
35


题解

线段树裸题

唯一要注意的是两种标记的处理:pushdown中始终是先乘后加,而在乘的时候把原有的加标记也乘上这个数。原理应该不难想。

  1 #include <cstdio>
  2 #include <cstring>
  3 #define lson l , mid , x << 1
  4 #define rson mid + 1 , r , x << 1 | 1
  5 typedef long long lint;
  6 lint mod , sum[400010] , add[400010] , mul[400010];
  7 void pushup(int x)
  8 {
  9     sum[x] = (sum[x << 1] + sum[x << 1 | 1]) % mod;
 10 }
 11 void pushdown(int l , int r , int x)
 12 {
 13     int mid = (l + r) >> 1;
 14     if(mul[x] != 1)
 15     {
 16         sum[x << 1] = sum[x << 1] * mul[x] % mod;
 17         sum[x << 1 | 1] = sum[x << 1 | 1] * mul[x] % mod;
 18         add[x << 1] = add[x << 1] * mul[x] % mod;
 19         add[x << 1 | 1] = add[x << 1 | 1] * mul[x] % mod;
 20         mul[x << 1] = mul[x << 1] * mul[x] % mod;
 21         mul[x << 1 | 1] = mul[x << 1 | 1] * mul[x] % mod;
 22         mul[x] = 1;
 23     }
 24     if(add[x])
 25     {
 26         sum[x << 1] = (sum[x << 1] + add[x] * (mid - l + 1)) % mod;
 27         sum[x << 1 | 1] = (sum[x << 1 | 1] + add[x] * (r - mid)) % mod;
 28         add[x << 1] = (add[x << 1] + add[x]) % mod;
 29         add[x << 1 | 1] = (add[x << 1 | 1] + add[x]) % mod;
 30         add[x] = 0;
 31     }
 32 }
 33 void build(int l , int r , int x)
 34 {
 35     mul[x] = 1;
 36     if(l == r)
 37     {
 38         scanf("%lld" , &sum[x]);
 39         sum[x] %= mod;
 40         return;
 41     }
 42     int mid = (l + r) >> 1;
 43     build(lson);
 44     build(rson);
 45     pushup(x);
 46 }
 47 void updatemul(int b , int e , lint m , int l , int r , int x)
 48 {
 49     if(b <= l && r <= e)
 50     {
 51         sum[x] = sum[x] * m % mod;
 52         add[x] = add[x] * m % mod;
 53         mul[x] = mul[x] * m % mod;
 54         return;
 55     }
 56     pushdown(l , r , x);
 57     int mid = (l + r) >> 1;
 58     if(b <= mid) updatemul(b , e , m , lson);
 59     if(e > mid) updatemul(b , e , m , rson);
 60     pushup(x);
 61 }
 62 void updateadd(int b , int e , lint a , int l , int r , int x)
 63 {
 64     if(b <= l && r <= e)
 65     {
 66         sum[x] = (sum[x] + a * (r - l + 1)) % mod;
 67         add[x] = (add[x] + a) % mod;
 68         return;
 69     }
 70     pushdown(l , r , x);
 71     int mid = (l + r) >> 1;
 72     if(b <= mid) updateadd(b , e , a , lson);
 73     if(e > mid) updateadd(b , e , a , rson);
 74     pushup(x);
 75 }
 76 lint query(int b , int e , int l , int r , int x)
 77 {
 78     if(b <= l && r <= e)
 79         return sum[x];
 80     pushdown(l , r , x);
 81     int mid = (l + r) >> 1;
 82     lint ans = 0;
 83     if(b <= mid) ans = (ans + query(b , e , lson)) % mod;
 84     if(e > mid) ans = (ans + query(b , e , rson)) % mod;
 85     return ans;
 86 }
 87 int main()
 88 {
 89     int n , m , p , l , r;
 90     lint k;
 91     scanf("%d%lld" , &n , &mod);
 92     build(1 , n , 1);
 93     scanf("%d" , &m);
 94     while(m -- )
 95     {
 96         scanf("%d%d%d" , &p , &l , &r);
 97         switch(p)
 98         {
 99             case 1: scanf("%lld" , &k); updatemul(l , r , k , 1 , n , 1); break;
100             case 2: scanf("%lld" , &k); updateadd(l , r , k , 1 , n , 1); break;
101             default: printf("%lld\n" , query(l , r , 1 , n , 1));
102         }
103     }
104     return 0;
105 }

 

【bzoj1798】[Ahoi2009]Seq 维护序列seq

原文:http://www.cnblogs.com/GXZlegend/p/6406433.html

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