zoukankan      html  css  js  c++  java
  • hdu4578 Transformation【线段树】

    Yuanfang is puzzled with the question below: 
    There are n integers, a 1, a 2, …, a n. The initial values of them are 0. There are four kinds of operations. 
    Operation 1: Add c to each number between a x and a y inclusive. In other words, do transformation a k<---a k+c, k = x,x+1,…,y. 
    Operation 2: Multiply c to each number between a x and a y inclusive. In other words, do transformation a k<---a k×c, k = x,x+1,…,y. 
    Operation 3: Change the numbers between a x and a y to c, inclusive. In other words, do transformation a k<---c, k = x,x+1,…,y. 
    Operation 4: Get the sum of p power among the numbers between a x and a y inclusive. In other words, get the result of a x p+a x+1 p+…+a y 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

    超麻烦的线段树 一共四种操作

    加 乘 赋值 幂

    分别用一个数组表示

    关键在于下方pushdown的操作

    赋值的时候就直接下放 保存的幂也直接求

    加和乘的操作一起下放 用平方和立方公式来求sum

    自己写的不知道为什么RE了 查了半天查不出来 而且好复杂懒得查了.....

    下面是题解的代码

    #include<stdio.h>
    #include<iostream>
    #include<stdlib.h>
    #include<string.h>
    #include<algorithm>
    #include<vector>
    using namespace std;
    #define maxn 110000
    #define lmin 1
    #define rmax n
    #define lson l,(l+r)/2,rt<<1
    #define rson (l+r)/2+1,r,rt<<1|1
    #define root lmin,rmax,1
    #define now l,r,rt
    #define int_now int l,int r,int rt
    #define INF 99999999
    #define LL int
    #define mod 10007
    LL add[maxn*4];
    LL mul[maxn*4];
    LL num[maxn*4];
    LL sum[maxn*4][4];
    void push_up(int_now)
    {
        for(int i=1; i<=3; i++)
            sum[rt][i]=(sum[rt<<1][i]+sum[rt<<1|1][i])%mod;
    }
    void push_down(int_now)
    {
        if(l==r)return;
        int ll=(r+l)/2-l+1;
        int rr=r-(r+l)/2;
        if(num[rt] != 0)
        {
            num[rt<<1] = num[rt<<1|1] = num[rt];
            add[rt<<1] = add[rt<<1|1] = 0;
            mul[rt<<1] = mul[rt<<1|1] = 1;
            sum[rt<<1][1] = (ll)*num[rt<<1]%mod;
            sum[rt<<1][2] = (ll)*num[rt<<1]%mod*num[rt<<1]%mod;
            sum[rt<<1][3] = (ll)*num[rt<<1]%mod*num[rt<<1]%mod*num[rt<<1]%mod;
            sum[(rt<<1)|1][1] = (rr)*num[rt<<1|1]%mod;
            sum[(rt<<1)|1][2] = (rr)*num[rt<<1|1]%mod*num[rt<<1|1]%mod;
            sum[(rt<<1)|1][3] = (rr)*num[rt<<1|1]%mod*num[rt<<1|1]%mod*num[rt<<1|1]%mod;
            num[rt] = 0;
        }
        if(add[rt] != 0 || mul[rt] != 1)
        {
            add[rt<<1] = ( mul[rt]*add[rt<<1]%mod + add[rt] )%mod;
            mul[rt<<1] = mul[rt<<1]*mul[rt]%mod;
            int sum1,sum2,sum3;
            sum1 = (sum[rt<<1][1]*mul[rt]%mod + (ll)*add[rt]%mod)%mod;
            sum2 = (mul[rt] * mul[rt] % mod * sum[rt<<1][2] % mod + 2*add[rt]*mul[rt]%mod * sum[rt<<1][1]%mod + (ll)*add[rt]%mod*add[rt]%mod)%mod;
            sum3 = mul[rt] * mul[rt] % mod * mul[rt] % mod * sum[rt<<1][3] % mod;
            sum3 = (sum3 + 3*mul[rt] % mod * mul[rt] % mod * add[rt] % mod * sum[rt<<1][2]) % mod;
            sum3 = (sum3 + 3*mul[rt] % mod * add[rt] % mod * add[rt] % mod * sum[rt<<1][1]) % mod;
            sum3 = (sum3 + (ll)*add[rt]%mod * add[rt] % mod * add[rt] % mod) % mod;
            sum[rt<<1][1] = sum1;
            sum[rt<<1][2] = sum2;
            sum[rt<<1][3] = sum3;
            add[rt<<1|1] = ( mul[rt]*add[rt<<1|1]%mod + add[rt] )%mod;
            mul[rt<<1|1] = mul[rt<<1|1] * mul[rt] % mod;
            sum1 = (sum[(rt<<1)|1][1]*mul[rt]%mod + (rr)*add[rt]%mod)%mod;
            sum2 = (mul[rt] * mul[rt] % mod * sum[(rt<<1)|1][2] % mod + 2*add[rt]*mul[rt]%mod * sum[(rt<<1)|1][1]%mod + (rr)*add[rt]%mod*add[rt]%mod)%mod;
            sum3 = mul[rt] * mul[rt] % mod * mul[rt] % mod * sum[(rt<<1)|1][3] % mod;
            sum3 = (sum3 + 3*mul[rt] % mod * mul[rt] % mod * add[rt] % mod * sum[(rt<<1)|1][2]) % mod;
            sum3 = (sum3 + 3*mul[rt] % mod * add[rt] % mod * add[rt] % mod * sum[(rt<<1)|1][1]) % mod;
            sum3 = (sum3 + (rr)*add[rt]%mod * add[rt] % mod * add[rt] % mod) % mod;
            sum[(rt<<1)|1][1] = sum1;
            sum[(rt<<1)|1][2] = sum2;
            sum[(rt<<1)|1][3] = sum3;
            add[rt] = 0;
            mul[rt] = 1;
     
        }
    }
    void creat(int_now)
    {
        add[rt]=0;
        mul[rt]=1;
        num[rt]=0;
        for(int i=1; i<=3; i++)sum[rt][i]=0;
        if(l!=r)
        {
            creat(lson);
            creat(rson);
        }
    }
    void update(int ll,int rr,int x,int k,int_now)
    {
        if(ll>r||rr<l)return;
        if(ll<=l&&rr>=r)
        {
            x=x%mod;
            if(k==1)
            {
                add[rt]=(add[rt]+x)%mod;
                sum[rt][3]=(sum[rt][3]+3*sum[rt][2]%mod*x%mod+3*sum[rt][1]%mod*x%mod*x%mod+x*x%mod*x%mod*(r-l+1)%mod)%mod;
                sum[rt][2]=(sum[rt][2]+(r-l+1)*x%mod*x%mod+2*x%mod*sum[rt][1]%mod)%mod;
                sum[rt][1]=(sum[rt][1]+x*(r-l+1)%mod)%mod;
            }
            else if(k==2)
            {
                mul[rt]=(mul[rt]*x)%mod;
                add[rt]=(add[rt]*x)%mod;
                for(int i=1; i<=3; i++)
                {
                    int j=i;
                    LL ans=1;
                    while(j--)ans=(ans*x)%mod;
                    sum[rt][i]=(sum[rt][i]*ans)%mod;
                }
            }
            else
            {
                num[rt]=x;
                mul[rt]=1;
                add[rt]=0;
                for(int i=1; i<=3; i++)
                {
                    int j=i;
                    LL ans=1;
                    while(j--)ans=(ans*x)%mod;
                    sum[rt][i]=(ans*(r-l+1)%mod)%mod;
                }
            }
            return;
        }
        push_down(now);
        update(ll,rr,x,k,lson);
        update(ll,rr,x,k,rson);
        push_up(now);
    }
    LL query(int ll,int rr,int p,int_now)
    {
        if(ll>r||rr<l)return 0;
        if(ll<=l&&rr>=r)
        {
            return sum[rt][p];
        }
        push_down(now);
        return (query(ll,rr,p,lson)+query(ll,rr,p,rson))%mod;
    }
    int main()
    {
        int n,m,k,a,b,c;
        while(~scanf("%d%d",&n,&m)&&(n||m))
        {
            creat(root);
            while(m--)
            {
                scanf("%d%d%d%d",&k,&a,&b,&c);
                if(k<=3)
                {
                    update(a,b,c,k,root);
                }
                else
                {
                    printf("%d
    ",query(a,b,c,root));
                }
            }
        }
        return 0;
    }
    

    RE的代码:

    
    #include<iostream>
    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    #include<stack>
    #define inf 1e18
    using namespace std;
    
    const int maxn = 110005;
    const int mod = 10007;
    int m, n;
    long long sum[maxn << 2][4], lazyadd[maxn<<2], lazymul[maxn<<2], lazynum[maxn<<2];
    
    void pushup(int rt)
    {
        for(int i = 1; i <= 3; i++){
            sum[rt][i] = (sum[rt << 1][i] + sum[rt << 1|1][i]) % mod;
        }
    }
    
    void build(int l, int r, int rt)
    {
        lazyadd[rt] = 0;
        lazymul[rt] = 1;
        lazynum[rt] = 0;
        for(int i = 1; i <= 3; i++)
            sum[rt][i] = 0;
        if(l == r) return;
        int m = (l + r) >> 1;
        build(l, m, rt << 1);
        build(m + 1, r, rt << 1 | 1);
    }
    
    void pushdown(int l, int r, int rt)
    {
        if(l == r) return;
        int m = (l + r) / 2;
        int lnum = m - l + 1, rnum = r - m;
        if(lazynum[rt]){//ж╠╫соб╥е
            lazynum[rt << 1] = lazynum[rt<<1|1] = lazynum[rt];
            lazyadd[rt<<1] = lazyadd[rt<<1|1] = 0;
            lazymul[rt<<1] = lazymul[rt<<1|1] = 1;
            sum[rt<<1][1] = lnum * lazynum[rt<<1] % mod;
            sum[rt<<1][2] = lnum * lazynum[rt<<1] % mod * lazynum[rt<<1] % mod;
            sum[rt<<1][3] = lnum * lazynum[rt<<1] % mod * lazynum[rt<<1] % mod * lazynum[rt<<1] % mod;
            sum[rt<<1|1][1] = rnum * lazynum[rt<<1|1] % mod;
            sum[rt<<1|1][2] = rnum * lazynum[rt<<1|1] % mod * lazynum[rt<<1|1] % mod;
            sum[rt<<1|1][3] = rnum * lazynum[rt<<1|1] % mod * lazynum[rt<<1|1] % mod * lazynum[rt<<1|1] % mod;
            lazynum[rt] = 0;
        }
        if(lazyadd[rt] || lazymul[rt] != 1){
            lazyadd[rt<<1] = (lazymul[rt] * lazyadd[rt<<1] % mod + lazyadd[rt])% mod;
            lazymul[rt<<1] = lazymul[rt] * lazymul[rt<<1] % mod;
            int sum1 = (sum[rt<<1][1] * lazymul[rt] % mod + lnum * lazyadd[rt] % mod) % mod;
            int sum2 = (sum[rt<<1][2] * lazymul[rt] % mod * lazymul[rt] % mod + 2 * lazyadd[rt] * lazymul[rt] % mod * sum[rt<<1][1] % mod + lnum * lazyadd[rt] % mod * lazyadd[rt] % mod) % mod;
            int sum3 = (sum[rt<<1][3] * lazymul[rt] % mod * lazymul[rt] % mod * lazymul[rt] % mod + lnum * lazyadd[rt] % mod * lazyadd[rt] % mod * lazyadd[rt] % mod) % mod;
            sum3 = (sum3 + 3 * lazymul[rt] * lazyadd[rt] % mod * lazyadd[rt] % mod * sum[rt<<1][1] % mod) % mod;
            sum3 = (sum3 + 3 * lazymul[rt] * lazymul[rt] % mod * lazyadd[rt] % mod * sum[rt<<1][2] % mod) % mod;
            sum[rt<<1][1] = sum1;
            sum[rt<<1][2] = sum2;
            sum[rt<<1][3] = sum3;
    
            lazyadd[rt<<1|1] = (lazymul[rt] * lazyadd[rt<<1|1] % mod + lazyadd[rt]) % mod;
            lazymul[rt<<1|1] = lazymul[rt] * lazymul[rt<<1|1] % mod;
            sum1 = (sum[rt<<1|1][1] * lazymul[rt] % mod + lnum * lazyadd[rt] % mod) % mod;
            sum2 = (sum[rt<<1|1][2] * lazymul[rt] % mod * lazymul[rt] % mod + 2 * lazyadd[rt] * lazymul[rt] % mod * sum[rt<<1|1][1] % mod + lnum * lazyadd[rt] % mod * lazyadd[rt] % mod) % mod;
            sum3 = (sum[rt<<1|1][3] * lazymul[rt] % mod * lazymul[rt] % mod * lazymul[rt] % mod + lnum * lazyadd[rt] % mod * lazyadd[rt] % mod * lazyadd[rt] % mod) % mod;
            sum3 = (sum3 + 3 * lazymul[rt] * lazyadd[rt] % mod * lazyadd[rt] % mod * sum[rt<<1|1][1] % mod) % mod;
            sum3 = (sum3 + 3 * lazymul[rt] * lazymul[rt] % mod * lazyadd[rt] % mod * sum[rt<<1|1][2] % mod) % mod;
            sum[rt<<1|1][1] = sum1;
            sum[rt<<1|1][2] = sum2;
            sum[rt<<1|1][3] = sum3;
    
            lazyadd[rt] = 0;
            lazymul[rt] = 1;
        }
    }
    
    void update(int L, int R, int x, int k, int l, int r, int rt)
    {
        if(L > r || R < l)return;
        if(L <= l && R >= r){
            x = x % mod;
            if(k == 1){
                lazyadd[rt] = (lazyadd[rt] + x) % mod;
                sum[rt][3] = (sum[rt][3] + 3 * sum[rt][2] % mod * x % mod + 3 * sum[rt][1] % mod * x % mod * x % mod + (r - l + 1) * x % mod * x % mod * x % mod) % mod;
                sum[rt][2] = (sum[rt][2] + 2 * sum[rt][1] % mod * x % mod + (r - l + 1) * x % mod * x % mod) % mod;
                sum[rt][1] = (sum[rt][1] + (r - l + 1) * x % mod) % mod;
            }
            else if(k == 2){
                lazymul[rt] = lazymul[rt] * x % mod;
                lazyadd[rt] = lazyadd[rt] * x % mod;
                for(int i = 1; i <= 3; i++){
                    int j = i;
                    long long ans = 1;
                    while(j--){
                        ans = (ans * x) % mod;
                    }
                    sum[rt][i] = (sum[rt][i] * ans) % mod;
                }
            }
            else{
                lazynum[rt] = x;
                lazymul[rt] = 1;
                lazyadd[rt] = 0;
                for(int i = 1; i <= 3; i++){
                    int j = i;
                    long long ans = 1;
                    while(j--){
                        ans = (ans * x) % mod;
                    }
                    sum[rt][i] = (ans * (r - l + 1) % mod) % mod;
                }
            }
            return;
        }
        pushdown(l, r, rt);
        int m = (l + r) / 2;
        update(L, R, x, k, l, m, rt<<1);
        update(L, R, x, k, m + 1, r, rt<<1|1);
        pushup(rt);
    }
    
    long long query(int L, int R, int p, int l, int r, int rt)
    {
        if(L > r || R < L) return 0;
        if(L <= l && R >= r){
            return sum[rt][p];
        }
        pushdown(l, r, rt);
        int m = (l + r) / 2;
        return (query(L, R, p, l, m, rt<<1) + query(L, R, p, m + 1, r, rt<<1|1)) % mod;
    
    }
    
    int main()
    {
        while(scanf("%d%d", &n, &m) != EOF && (n || m)){
            build(1, n, 1);
            int k, x, y, c;
            for(int i = 0; i < m; i++){
                scanf("%d%d%d%d", &k, &x, &y, &c);
                if(k == 4){
                    printf("%lld
    ", query(x, y, c, 1, n, 1));
                }
                else{
                    update(x, y, c, k, 1, n, 1);
                }
            }
        }
        return 0;
    }
    
  • 相关阅读:
    jmeter csv参数化测试数据并实现自动断言
    jmeter https脚本录制
    jmeter正则表达式提取器
    jmeter逻辑控制器
    jmeter参数化
    IP地址与整数之间的转换
    UML类图与类的关系详解
    关于es6中let的相关问题
    XML、XHTML、HTML相关知识总结
    浅谈javascript中for循环和for...in循环的区别
  • 原文地址:https://www.cnblogs.com/wyboooo/p/9643392.html
Copyright © 2011-2022 走看看