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;
    }
    
  • 相关阅读:
    IDEA Tomcat控制台乱码
    使用Vue写一个登录页面
    vue如何新建一个项目并使用webstorm运行
    关于无线充电的三大标准和四种实现方式的介绍
    使用aria2搭建离线下载服务器
    OnPaint和OnDraw的区别
    PE文件中的DllCharacteristics属性
    ACM/IOI 历年国家集训队论文集和论文算法分类整理
    安装完最小化 RHEL/CentOS 7 后需要做的 30 件事情7. 安装 PHP PHP 是用于 web 基础服务的服务器端脚本语言。它也经常被用作通用编程语言。在最小化安装的 CentOS 中安
    堆栈—冲刺十三模拟赛 外星密码
  • 原文地址:https://www.cnblogs.com/wyboooo/p/9643392.html
Copyright © 2011-2022 走看看