题意:

初始n个空串,m个操作:

1.给[l,r]的所有字符串头尾加一个‘d’,将原字符串x变为dxd

2.求[l,r]所有字符串代表的数字之和mod 1e9+7

思路:

据说是硬核线段树。。

对于线段树我们要先找出来对于一个区间改变的时候对要询问的区间(sum)造成的变化

对于一个数x,如果对他操作了一次(头尾加一个c),那么它将变成$10x+c+c*10^{n_i+1}$,其中$n_i$表示x的实际长度(位数)

那么对当前区间操作时,当前区间的sum会变成$10sum+(r-l+1)*c+c*sumlen$,其中$sumlen=\sum_{i=l}^{r}10^{n_i+1}$

这个东西是应该写在要打懒惰标记的地方的

上式显然是有先后操作顺序的,我们只需要将操作系列$d_3d_2d_1xd_1d_2d_3$分成$d_3d_2d_1$和$d_1d_2d_3$(用两个数保存),用两个懒惰标记addl和addr分别保存

不过在pushdown的时候要注意,懒惰标记存在于已经操作过的最后一个节点里,所以要注意次序与操作的对象

在pushdown中,如果只是下传到一个节点(比如是lc),

那么$sum[lc]=addr[root]+sum[lc]*addlen[root]+addl[root]*addlen[root]*10^{n_i+1}/10$

所以对整个lc区间,$sum[lc]=\sum addr[root]+sum[lc]*addlen[root]+addl[root]+addl[root]*addlen[root]*sumlen[root]/10$

其他的都是常规操作了,注意乘的时候别溢出了

代码:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<string>
#include<stack>
#include<queue>
#include<deque>
#include<set>
#include<vector>
#include<map> #define fst first
#define sc second
#define pb push_back
#define mem(a,b) memset(a,b,sizeof(a))
#define lson l,mid,root<<1
#define rson mid+1,r,root<<1|1
#define lc root<<1
#define rc root<<1|1
#define lowbit(x) ((x)&(-x)) using namespace std; typedef double db;
typedef long double ldb;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> PI;
typedef pair<ll,ll> PLL; const db eps = 1e-;
const int mod = 1e9+;
const int maxn = 2e6+;
const int maxm = 2e6+;
const int inf = 0x3f3f3f3f;
const db pi = acos(-1.0); ll fp(ll a, ll n){
ll ans = ;
while(n){
if(n & ) ans *= a;
a *= a;
a %= mod;
n >>= ;
ans %= mod;
}
return ans;
}
ll div10;
ll sum[maxn];
ll sumlen[maxn];
ll addl[maxn],addr[maxn],addlen[maxn];
int t;
int n, m;
void build(int l, int r, int root){
int mid = (l+r)>>;
addl[root]=addr[root]=;
addlen[root]=;
if(l==r){
sum[root] = ;
sumlen[root] = ;
return;
}
build(lson);
build(rson);
sum[root]=;
sumlen[root]=sumlen[lc]+sumlen[rc];
sumlen[root]%=mod;
return;
}
void pushdown(int l, int r, int root){
int mid = (l+r)>>;
if(addlen[root]>){
addl[lc]=(addl[root]*addlen[lc]%mod+addl[lc])%mod;
addl[rc]=(addl[root]*addlen[rc]%mod+addl[rc])%mod;
addr[lc]=(addr[lc]*addlen[root]%mod+addr[root])%mod;
addr[rc]=(addr[rc]*addlen[root]%mod+addr[root])%mod;
addlen[lc]=addlen[lc]*addlen[root]%mod;
addlen[rc]=addlen[rc]*addlen[root]%mod; sum[lc]=(addr[root]*(mid-l+)%mod+sum[lc]*addlen[root]%mod+addl[root]*addlen[root]%mod*sumlen[lc]%mod*div10%mod)%mod;
sum[rc]=(addr[root]*(r-mid)%mod+sum[rc]*addlen[root]%mod+addl[root]*addlen[root]%mod*sumlen[rc]%mod*div10%mod)%mod; sumlen[lc]=(sumlen[lc]*addlen[root]%mod*addlen[root]%mod)%mod;
sumlen[rc]=(sumlen[rc]*addlen[root]%mod*addlen[root]%mod)%mod; addl[root]=addr[root]=;
addlen[root]=;
}
}
void update(int ql, int qr, ll val, int l, int r, int root){
int mid = (l+r)>>;
if(ql<=l&&r<=qr){
sum[root]=(*sum[root]%mod+(r-l+)*val%mod+val*sumlen[root]%mod)%mod;
sumlen[root]=sumlen[root]*%mod;
addl[root]=(addl[root]+val*addlen[root])%mod;
addr[root]=(addr[root]*+val)%mod;
addlen[root]=(addlen[root]*)%mod;
return;
}
pushdown(l,r,root);
if(ql<=mid)update(ql,qr,val,lson);
if(qr>mid)update(ql,qr,val,rson);
sum[root]=(sum[lc]+sum[rc])%mod;
sumlen[root]=(sumlen[lc]+sumlen[rc])%mod;
return;
}
ll query(int ql, int qr, int l, int r, int root){
int mid = (l+r)>>;
if(ql<=l&&r<=qr)return sum[root]%mod;
ll ans = ;
pushdown(l,r,root);
if(ql<=mid)ans+=query(ql,qr,lson);
if(qr>mid)ans+=query(ql,qr,rson);
return ans%mod;
}
char op[];
int main(){
scanf("%d", &t);
div10=fp(,mod-)%mod;
for(int ncase = ; ncase <= t; ncase++){
scanf("%d %d", &n, &m);
build(,n,);
printf("Case %d:\n",ncase);
while(m--){
ll w;
int x, y;
scanf("%s",op+);
scanf("%d %d", &x, &y);
if(op[]=='w'){
scanf("%lld", &w);
update(x, y, w, , n, );
}
else{
printf("%lld\n",query(x,y,,n,)%mod);
}
} } return ;
}
/*
2
3 3
wrap 1 3 1
wrap 2 4 3
query 1 2
4 4
wrap 1 3 0
wrap 2 4 3
query 1 4
query 2 3 1
4 4
wrap 1 3 0
wrap 2 4 3 3
4 4
wrap 1 4 2
wrap 1 4 3
wrap 1 4 1
wrap 2 4 6
3 2
wrap 1 3 0
wrap 2 2 1
5 3
wrap 1 5 1
wrap 2 6 0
wrap 3 5 2
*/

HDU 6562 lovers 2018CCPC吉林H(线段树)的更多相关文章

  1. HDU 3074.Multiply game-区间乘法-线段树(单点更新、区间查询),上推标记取模

    Multiply game Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Tot ...

  2. hdu 5274 Dylans loves tree(LCA + 线段树)

    Dylans loves tree Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Othe ...

  3. HDU 1394 Minimum Inversion Number(线段树求最小逆序数对)

    HDU 1394 Minimum Inversion Number(线段树求最小逆序数对) ACM 题目地址:HDU 1394 Minimum Inversion Number 题意:  给一个序列由 ...

  4. HDU 5875 Function (2016年大连网络赛 H 线段树+gcd)

    很简单的一个题的,结果后台数据有误,自己又太傻卡了3个小时... 题意:给你一串数a再给你一些区间(lef,rig),求出a[lef]%a[lef+1]...%a[rig] 题解:我们可以发现数字a对 ...

  5. hdu 1556:Color the ball(线段树,区间更新,经典题)

    Color the ball Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)To ...

  6. hdu 1255 覆盖的面积(线段树 面积 交) (待整理)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1255 Description 给定平面上若干矩形,求出被这些矩形覆盖过至少两次的区域的面积.   In ...

  7. HDU 1828 / POJ 1177 Picture (线段树扫描线,求矩阵并的周长,经典题)

    做这道题之前,建议先做POJ 1151  Atlantis,经典的扫描线求矩阵的面积并 参考连接: http://www.cnblogs.com/scau20110726/archive/2013/0 ...

  8. hdu 1754 I Hate It (模板线段树)

    http://acm.hdu.edu.cn/showproblem.php?pid=1754 I Hate It Time Limit: 9000/3000 MS (Java/Others)    M ...

  9. HDU 1166 敌兵布阵(线段树 单点更新)

     点我看题目  题意 :HDU的中文题也不常见....这道题我就不详述了..... 思路 :这个题用线段树用树状数组都可以,用线段树的时候要注意输入那个地方,输入一个字符串的时候不要紧接着输入两个数字 ...

随机推荐

  1. 单用户登陆demo-后者挤到前者,类似QQ

    单用户登陆demo ,采用的是Tp5. 流程是,当用户首次登陆是验证用户帐号密码,成功的,用当前时间戳加上用户id和ip 拼接成一个标识,暂且sign ,然后存入cookie ,时间戳存入缓存redi ...

  2. Spring注解:InitBinder

    注解 InitBinder 是用来初始化绑定器Binder的,而Binder是用来绑定数据的,换句话说就是将请求参数转成数据对象. @InitBinder用于在@Controller中标注于方法,表示 ...

  3. IPython的介绍与使用

    1.IPython简介 ipython是一个python的交互式shell,比默认的python shell好用得多,支持变量自动补全,自动缩进,支持bash shell命令,内置了许多很有用的功能和 ...

  4. 区间dp - 全部按下一列石头

    There is one last gate between the hero and the dragon. But opening the gate isn't an easy task. The ...

  5. typescript学习笔记(一)---基础变量类型

    作为一个前端开发者,学习新技术跟紧大趋势是必不可少的.随着2019年TS的大火,我打算利用一个月的时间学习这门语言.接下来的几篇文章是我学习TS的学习笔记,其中也会掺杂一些学习心得.话不多说,先从基础 ...

  6. scrapy在存储数据到json文件中时,中文变成为\u开头的字符串的处理方法

    在settings.py文件中添加 FEED_EXPORT_ENCODING = 'utf-8'

  7. 十大排序算法(Java实现)

    一.冒泡排序(Bubble Sort) public class BubbleSort { public static void main(String[] args) { int[] arr = { ...

  8. 【Java面试】Mybatis篇

    1.MyBatis编程步骤是什么样的? ① 创建SqlSessionFactory ② 通过SqlSessionFactory创建SqlSession ③ 通过sqlsession执行数据库操作 ④  ...

  9. 查看jvm内存信息

    Runtime.getRuntime().maxMemory(); //最大可用内存,对应-Xmx Runtime.getRuntime().freeMemory(); //当前JVM空闲内存 Run ...

  10. 8、python运算符

    前言:本文主要介绍python中经常使用的6种运算符,分别是算术运算符.比较运算符.赋值运算符.逻辑运算符.身份运算符和成员运算符. (因为用法比较简单,这里只做介绍,有兴趣的可以自己敲代码运行一下) ...