Transformation 线段树好题 好题 (独立写出来对线段树不容易)

Transformation

Time Limit: 15000/8000 MS (Java/Others)    Memory Limit: 65535/65536 K (Java/Others)
Total Submission(s): 7144    Accepted Submission(s): 1811


Problem Description
Yuanfang is puzzled with the question below:
There are n integers, a1, a2, …, an. The initial values of them are 0. There are four kinds of operations.
Operation 1: Add c to each number between ax and ay inclusive. In other words, do transformation ak<---ak+c, k = x,x+1,…,y.
Operation 2: Multiply c to each number between ax and ay inclusive. In other words, do transformation ak<---ak×c, k = x,x+1,…,y.
Operation 3: Change the numbers between ax and ay to c, inclusive. In other words, do transformation ak<---c, k = x,x+1,…,y.
Operation 4: Get the sum of p power among the numbers between ax and ay inclusive. In other words, get the result of axp+ax+1p+…+ay p.
Yuanfang has no idea of how to do it. So he wants to ask you to help him.
 
Input
There are no more than 10 test cases.
For each case, the first line contains two numbers n and m, meaning that there are n integers and m operations. 1 <= n, m <= 100,000.
Each the following m lines contains an operation. Operation 1 to 3 is in this format: "1 x y c" or "2 x y c" or "3 x y c". Operation 4 is in this format: "4 x y p". (1 <= x <= y <= n, 1 <= c <= 10,000, 1 <= p <= 3)
The input ends with 0 0.
 
Output
For each operation 4, output a single integer in one line representing the result. The answer may be quite large. You just need to calculate the remainder of the answer when divided by 10007.
 
Sample Input
5 5 3 3 5 7 1 2 4 4 4 1 5 2 2 2 5 8 4 3 5 3 0 0
 
Sample Output
307 7489
 
这题是好题  
太太太恶心了
简直爆炸  ,这题我写了N次
取模取模  
最后的query也要取模
找BUG找了好久找不到
这题最傻逼的做法是用3个lazy 和 3 个sum 
但是这里对于不同的lazy优先级不同 
而且还有取模操作,那样写下来及其的繁琐
我参考大佬博客 发现这题最优化的写法应该是
开一个线段树 维护区间里面相同的值
这样的话无论C多少都好求
        for (int i = 1 ; i <= c ; i++)
               ans = (ans * tree[rt].eq) % mod;
        return (ans * ((tree[rt].r - tree[rt].l + 1) % mod) % mod) % mod;
如果C是10用多个lazy维护代码量就直接爆炸了
这样的方法还有一个很好的优化
就是pushdown操作一直递归下去,直到到达底层
这样的话就有效的解决繁琐的优先级处理问题
这样处理优先级问题就很容易了
我菜爆了,用线段树维护区间相同的值 ,太强了
 
附送一个fuck函数
 
  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <algorithm>
  5 #include <queue>
  6 #include <stack>
  7 using namespace std;
  8 typedef long long LL;
  9 #define fuck(x) cout<<"["<<x<<"]";
 10 #define  rtl rt<<1
 11 #define  rtr rt<<1|1
 12 const int maxn = 1e5 + 10;
 13 const int mod = 1e4 + 7;
 14 const int INF = 2e9 + 7;
 15 int n, m;
 16 struct node {
 17     int l, r, eq, add, mul;
 18     int mid() {
 19         return (l + r) >> 1;
 20     }
 21 } tree[maxn << 2];
 22 void build(int l, int r, int rt) {
 23     tree[rt].l = l, tree[rt].r = r;
 24     tree[rt].add = 0, tree[rt].mul = 1, tree[rt].eq = -1;
 25     if (l == r) {
 26         tree[rt].eq = 0;
 27         return ;
 28     }
 29     int m = (l + r) >> 1;
 30     build(l, m, rtl);
 31     build(m + 1, r, rtr);
 32 }
 33 void pushdown(int rt) {
 34     if (tree[rt].l == tree[rt].r) return ;
 35     if (tree[rt].eq != -1) {
 36         tree[rtl].eq = tree[rtr].eq = tree[rt].eq;
 37         tree[rtl].add = tree[rtr].add = 0;
 38         tree[rtl].mul = tree[rtr].mul = 1;
 39         tree[rt].eq = -1;
 40         return ;
 41     }
 42     if (tree[rt].mul != 1) {
 43         if (tree[rtl].eq != -1) tree[rtl].eq = (tree[rtl].eq * tree[rt].mul) % mod;
 44         else {
 45             pushdown(rtl);
 46             tree[rtl].mul = (tree[rtl].mul * tree[rt].mul) % mod;
 47         }
 48         if (tree[rtr].eq != -1) tree[rtr].eq = (tree[rtr].eq * tree[rt].mul) % mod;
 49         else {
 50             pushdown(rtr);
 51             tree[rtr].mul = (tree[rtr].mul * tree[rt].mul) % mod;
 52         }
 53         tree[rt].mul = 1;
 54     }
 55     if (tree[rt].add) {
 56         if (tree[rtl].eq != -1) tree[rtl].eq = (tree[rtl].eq + tree[rt].add) % mod;
 57         else {
 58             pushdown(rtl);
 59             tree[rtl].add = (tree[rtl].add + tree[rt].add) % mod;
 60         }
 61         if (tree[rtr].eq != -1) tree[rtr].eq = (tree[rtr].eq + tree[rt].add) % mod;
 62         else {
 63             pushdown(rtr);
 64             tree[rtr].add = (tree[rtr].add + tree[rt].add) % mod;
 65         }
 66         tree[rt].add = 0;
 67     }
 68 }
 69 
 70 void update(int L, int R, int rt, int op, int c) {
 71     if (L <= tree[rt].l && tree[rt].r <= R ) {
 72         if (op == 3) {
 73             tree[rt].eq = c;
 74             tree[rt].mul = 1;
 75             tree[rt].add = 0;
 76             return ;
 77         }
 78         if (tree[rt].eq != -1) {
 79             if (op == 1) tree[rt].eq = (tree[rt].eq + c) % mod;
 80             else tree[rt].eq = (tree[rt].eq * c) % mod;
 81         } else {
 82             pushdown(rt);
 83             if (op == 1) tree[rt].add = (tree[rt].add + c) % mod;
 84             else tree[rt].mul = (tree[rt].mul * c) % mod;
 85         }
 86         return ;
 87     }
 88     pushdown(rt);
 89     int m = tree[rt].mid();
 90     if (L <= m) update(L, R, rtl, op, c);
 91     if (R > m)  update(L, R, rtr, op, c);
 92 }
 93 
 94 int query(int L, int R, int rt, int c) {
 95     if (L <= tree[rt].l && tree[rt].r <= R && tree[rt].eq != -1) {
 96         int ans = 1;
 97         for (int i = 1 ; i <= c ; i++)
 98             ans = (ans * tree[rt].eq) % mod;
 99         return (ans * ((tree[rt].r - tree[rt].l + 1) % mod) % mod) % mod;
100     }
101     pushdown(rt);
102     int m = tree[rt].mid();
103     if (R <= m) return  query(L, R, rtl, c);
104     else if (L > m) return  query(L, R, rtr, c);
105     else  return  query(L, m, rtl, c) + query(m + 1, R, rtr, c);
106 }
107 int main() {
108     while(scanf("%d%d", &n, &m) != EOF) {
109         if (n == 0 && m == 0) break;
110         build(1, n, 1);
111         while(m--) {
112             int op, x, y, c;
113             scanf("%d%d%d%d", &op, &x, &y, &c);
114             if (op == 4) printf("%d
", query(x, y, 1, c)%mod);
115             else update(x, y, 1, op, c);
116         }
117     }
118     return 0;
119 }
 
原文地址:https://www.cnblogs.com/qldabiaoge/p/9380209.html