• 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 }
     
  • 相关阅读:
    Centos下,Docker部署Yapi接口管理平台(详细得令人发指)
    Centos7下安装Docker(详细的新手装逼教程)
    性能测试之nmon对linux服务器的监控
    真爱至上,谈谈我的测试经历(二)
    linux问题点滴,给普通用户添加sudo权限
    浅谈软件测试流程(一)
    面试如何谈笑风生,软件测试基础理论整理
    测试与开发如何有效沟通,QC11(HP ALM 11)的简单使用记录
    解决github访问过慢问题
    Python语言下图像的操作方法总结
  • 原文地址:https://www.cnblogs.com/qldabiaoge/p/9380209.html
Copyright © 2020-2023  润新知