zoukankan      html  css  js  c++  java
  • 2018 CCPC 吉林站 H Lovers || HDU 6562 (线段树哦)

     

    http://acm.hdu.edu.cn/showproblem.php?pid=6562

    题意:

    q次操作

    1.将第l~r个数的左边和和右边都加上一个数d, 使得这个数变成 dsiddsid的形式

    2.询问区间和.

    题解:对于一个数字x若执行第一个操作则  

    则若对于一个区间sum(l,r)执行第一个操作则  

    设 

    则便可以用线段树去维护这两个东西便可,这里只考虑了d是一位数的情况,但是在线段树下传标记的过程中可能一个区间多次执行第一个操作,那么wrap的d便不是一位数,而且左右两边的d是镜像的,我们便要用两个lazy标记,lazy1维护左边加的数,lazy2维护右边加的数,同时可以用lazylen表示这两个lazy的,然后好好考虑一下如何维护sum和sumlen即可

    个人感悟:在敲的时候思路是基本对的 , 但是我在维护 的时候 为了计算10的多少次幂,我维护的是一个长度 ,然后查询的时候,用一个阶乘的fac10[]数组 , 果然RE了 , 大神的代码, 发现别人维护的是一个10^(len)的值,其实细想也是,我们主要维护的就是这个,我居然多次了一举,太菜了我

    #include <iostream>
    #include <string.h>
    #include <algorithm>
    #include <stdio.h>
    #include <math.h>
    #include <queue>
    #define MAXN 400010
    #define inf 0x3f3f3f3f
    #define LL long long
    using namespace std;
    const int N=1e7+5;
    const int mod = 1e9+7;
    struct node{
        int l,r; //区间[l,r]
        LL addl,addr; //区间的延时标记
        LL sum,laz,all; /// 区间和 laz增加位数 all=10^位数
    }tree[MAXN<<2];//一定要开到4倍多的空间
    void pushup(int index) {
        tree[index].sum = (tree[index<<1].sum+tree[index<<1|1].sum)%mod;
        tree[index].all = (tree[index<<1].all+tree[index<<1|1].all)%mod;
    }
    void pushdown(int index) {
        if(tree[index].laz > 1) {
            tree[index<<1].addl = (tree[index].addl*tree[index<<1].laz%mod + tree[index<<1].addl%mod)%mod;
            tree[index<<1|1].addl = (tree[index].addl*tree[index<<1|1].laz%mod + tree[index<<1|1].addl%mod)%mod;
    
            tree[index<<1].addr = (tree[index<<1].addr*tree[index].laz%mod + tree[index].addr%mod)%mod;
            tree[index<<1|1].addr = (tree[index<<1|1].addr*tree[index].laz%mod+ tree[index].addr)%mod;
    
    
            tree[index<<1].sum = (( tree[index<<1].sum*tree[index].laz%mod
                                + tree[index].addl*tree[index<<1].all%mod*tree[index].laz%mod)%mod
                                + tree[index].addr*(tree[index<<1].r-tree[index<<1].l+1)%mod)%mod;
            tree[index<<1|1].sum = ((tree[index<<1|1].sum*tree[index].laz%mod
                                + tree[index].addl*tree[index<<1|1].all%mod*tree[index].laz%mod)%mod
                                + tree[index].addr*(tree[index<<1|1].r-tree[index<<1|1].l+1)%mod)%mod;
    
            tree[index<<1].all = (tree[index<<1].all*tree[index].laz%mod*tree[index].laz)%mod;
            tree[index<<1|1].all = (tree[index<<1|1].all*tree[index].laz%mod*tree[index].laz)%mod;
            tree[index<<1].laz = tree[index].laz*tree[index<<1].laz%mod;
            tree[index<<1|1].laz = tree[index].laz*tree[index<<1|1].laz%mod;
            tree[index].laz = 1;
    
            tree[index].addl = 0;
            tree[index].addr = 0;
        }
    
    }
    void build(int l,int r,int index){
        tree[index].sum = 0;
        tree[index].l = l; tree[index].r = r;
        tree[index].addl = tree[index].addr = 0;
        tree[index].laz = 1;//刚开始一定要清0
        if(l == r) {
            tree[index].all = 1;
            return ;
        }
        int mid = (l+r)>>1;
        build(l,mid,index<<1);
        build(mid+1,r,index<<1|1);
        pushup(index);
    }
    void update(int l,int r,int index,LL val) {
        if(l <= tree[index].l && r >= tree[index].r) {
            tree[index].sum = ((tree[index].sum*10%mod
                                + val*(tree[index].r-tree[index].l+1)%mod)%mod
                                + val*10*tree[index].all %mod )%mod ;
            tree[index].all = tree[index].all*100%mod;
            tree[index].addl = (val*tree[index].laz%mod + tree[index].addl)%mod;
            tree[index].laz = tree[index].laz*10%mod;
            tree[index].addr = (tree[index].addr*10%mod + val)%mod;
            return ;
        }
        pushdown(index);
        int mid = (tree[index].l+tree[index].r)>>1;
        if(l <= mid) update(l,r,index<<1,val);
        if(r > mid) update(l,r,index<<1|1,val);
        pushup(index);
    }
    LL query(int l,int r,int index) {
        if(l <= tree[index].l && r >= tree[index].r) {
            return tree[index].sum;
        }
        pushdown(index);
        int mid = (tree[index].l+tree[index].r)>>1;
        LL ans = 0;
        if(l <= mid) ans = (ans+query(l,r,index<<1))%mod;
        if(r > mid) ans = (ans+query(l,r,index<<1|1))%mod;
        return ans;
    }
    int main()
    {
        int _; scanf("%d",&_);
        for(int ncase=1;ncase<=_;ncase++) {
            int n,m; scanf("%d%d",&n,&m);
            printf("Case %d:
    ",ncase);
            build(1,n,1);
            while(m--) {
                char s[10]; scanf("%s",s);
                int l,r,v; scanf("%d%d",&l,&r);
                if(s[0]=='w') {
                    scanf("%d",&v); update(l,r,1,v);
                } else {
                    printf("%lld
    ",query(l,r,1));
                }
            }
        }
        return 0;
    }
    View Code
  • 相关阅读:
    CORS--跨域资源共享
    https协议
    http协议
    TCP/IP协议
    hashcode和equals方法
    单例模式
    Linux上安装Oracle的教程-centos7
    Linux命令大全
    初学者如何快速入门人工智能?(附资源)
    初学者如何从零开始学习人工智能?看完你就懂了
  • 原文地址:https://www.cnblogs.com/shuaihui520/p/11200227.html
Copyright © 2011-2022 走看看