Lovers
Time Limit: 25000/15000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)
Total Submission(s): 351 Accepted Submission(s): 104
Problem Description
The Fool comes to a cross-road, filled with energy, confidence and purpose, knowing exactly where he wants to go and what he wants to do. But he comes to a dead stop. A flowering tree marks the path he wants to take, the one he’s been planning on taking. But standing before a fruit tree marking the other path is a woman. The Fool has met and had relationships with women before, some far more beautiful and alluring. But she is different. Seeing her, he feels as though he’s just been shot in the heart with cupid’s arrow.
There are n empty strings:
s1, s2, . . . , sn.
You are required to perform two kinds of operations:
- wrap l r d: change si to dsid for all l ≤ i ≤ r, where d is a digit character.
- query l r: query ∑i=lr value(si) (mod 109 + 7), where value(s) is the number that string s represents.
- Note that the value of an empty string is 0.
Input
The first line contains one integer T, which denote the number of cases.
For each case, the first line contains two integer n and m where n is the number of strings and m is the number of operations.
Each line of the following m lines contains an operation with format
wrap l r d
or
query l r
.
Output
For each case, you should output "Case i:"in a line, where i is the case number starting from 1.
Then for each query operation in that case, output a line that contains a single integer that representing the answer for that query operation.
Sample Input
2
3 2
wrap 1 3 1
query 1 2
4 4
wrap 1 3 0
wrap 2 4 3
query 1 4
query 2 3
Sample Output
Case 1:
22
Case 2:
6039
6006
Hint
1 ≤ T ≤ 5, 1 ≤ n, m ≤ 1e5, 1 ≤ l ≤ r ≤ n.
Source
/*******
题解:对于一个数字x若执行第一个操作则
则若对于一个区间sum(l,r)执行第一个操作则
设 则便可以用线段树去维护这两个东西便可,这里只考虑了d是一位数的情况,但是在线段树下传标记的过程中可能一个区间多次执行第一个操作,那么wrap的d便不是一位数,而且左右两边的d是镜像的,我们便要用两个lazy标记,lazy1维护左边加的数,lazy2维护右边加的数,同时可以用lazylen表示这两个lazy的,然后好好考虑一下如何维护sum和sumlen即可
---------------------
作者:Sher杨
来源:CSDN
原文:https://blog.csdn.net/sudu6666/article/details/89887056
版权声明:本文为博主原创文章,转载请附上博文链接!
*******/
#include <bits/stdc++.h>
#define ll long long
#define db double
using namespace std;
const ll mod = 1e9 + 7;
const int mn = 1e5 + 10;
ll sum[4 * mn], len[4 * mn], lazy1[4 * mn], lazy2[4 * mn], lazylen[4 * mn];
void build(int id, int l, int r)
{
sum[id] = 0;
len[id] = lazylen[id] = 1;
lazy1[id] = lazy2[id] = 0;
if (l == r)
return;
int mid = (l + r) >> 1;
build(2 * id, l, mid);
build(2 * id + 1, mid + 1, r);
sum[id] = (sum[2 * id] + sum[2 * id + 1]) % mod;
len[id] = (len[2 * id] + len[2 * id + 1]) % mod;
}
void pushdown(int id, int l, int r)
{
if (lazylen[id] == 1) return;
lazy1[2 * id] = (lazy1[id] * lazylen[2 * id] % mod + lazy1[2 * id]) % mod;
lazy1[2 * id + 1] = (lazy1[id] * lazylen[2 * id + 1] % mod + lazy1[2 * id + 1]) % mod;
lazy2[2 * id] = (lazy2[2 * id] * lazylen[id] % mod + lazy2[id]) % mod;
lazy2[2 * id + 1] = (lazy2[2 * id + 1] * lazylen[id] % mod + lazy2[id]) % mod;
int mid = (l + r) >> 1;
sum[2 * id] = (lazy1[id] * len[2 * id] % mod * lazylen[id] % mod + sum[2 * id] * lazylen[id] % mod + lazy2[id] * (mid - l + 1)) % mod;
sum[2 * id + 1] = (lazy1[id] * len[2 * id + 1] % mod * lazylen[id] % mod + sum[2 * id + 1] * lazylen[id] % mod + lazy2[id] * (r - mid)) % mod;
len[2 * id] = len[2 * id] * lazylen[id] % mod * lazylen[id] % mod;
len[2 * id + 1] = len[2 * id + 1] * lazylen[id] % mod * lazylen[id] % mod;
lazylen[2 * id] = (lazylen[2 * id] * lazylen[id]) % mod;
lazylen[2 * id + 1] = (lazylen[2 * id + 1] * lazylen[id]) % mod;
lazy1[id] = 0, lazy2[id] = 0, lazylen[id] = 1;
}
void update(int L, int R, ll k, int id, int l, int r)
{
if (L == l && r == R)
{
sum[id] = (k * len[id] % mod * 10 % mod + sum[id] * 10 % mod + k * (r - l + 1) % mod) % mod;
len[id] = len[id] * 100 % mod;
lazy1[id] = (k * lazylen[id] % mod + lazy1[id]) % mod;
lazy2[id] = (lazy2[id] * 10 + k) % mod;
lazylen[id] = lazylen[id] * 10 % mod;
return;
}
pushdown(id, l, r);
int mid = (l + r) >> 1;
if (R <= mid) update(L, R, k, 2 * id, l, mid);
else if (mid + 1 <= L) update(L, R, k, 2 * id + 1, mid + 1, r);
else
{
update(L, mid, k, 2 * id, l, mid);
update(mid + 1, R, k, 2 * id + 1, mid + 1, r);
}
sum[id] = (sum[2 * id] + sum[2 * id + 1]) % mod;
len[id] = (len[2 * id] + len[2 * id + 1]) % mod;
}
ll query(int L, int R, int id, int l, int r)
{
if (L == l && r == R)
return sum[id];
pushdown(id, l, r);
int mid = (l + r) >> 1;
if (R <= mid) return query(L, R, 2 * id, l, mid);
else if (mid + 1 <= L) return query(L, R, 2 * id + 1, mid + 1, r);
else return (query(L, mid, 2 * id, l, mid) + query(mid + 1, R, 2 * id + 1, mid + 1, r)) % mod;
}
int main()
{
int T;
scanf("%d", &T);
for (int cas = 1; cas <= T; cas++)
{
printf("Case %d:\n", cas);
int n, m;
scanf("%d %d", &n, &m);
build(1, 1, n);
while (m--)
{
char ch[10]; scanf("%s", ch);
int l, r;
ll k;
if (ch[0] == 'w')
{
scanf("%d %d %lld", &l, &r, &k);
update(l, r, k, 1, 1, n);
}
else if (ch[0] == 'q')
{
scanf("%d %d", &l, &r);
printf("%lld\n", query(l, r, 1, 1, n));
}
}
}
return 0;
}