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
原文地址:https://www.cnblogs.com/shuaihui520/p/11200227.html