Codeforces 794F. Leha and security system 线段树
Bankopolis, the city you already know, finally got a new bank opened! Unfortunately, its security system is not yet working fine... Meanwhile hacker Leha arrived in Bankopolis and decided to test the system!
Bank has n cells for clients' money. A sequence from n numbers a1, a2, ..., an describes the amount of money each client has. Leha wants to make requests to the database of the bank, finding out the total amount of money on some subsegments of the sequence and changing values of the sequence on some subsegments. Using a bug in the system, Leha can requests two types of queries to the database:
- 1 l r x y denoting that Leha changes each digit x to digit y in each element of sequence ai, for which l ≤ i ≤ r is holds. For example, if we change in number 11984381 digit 8 to 4, we get 11944341. It's worth noting that Leha, in order to stay in the shadow, never changes digits in the database to 0, i.e. y ≠ 0.
- 2 l r denoting that Leha asks to calculate and print the sum of such elements of sequence ai, for which l ≤ i ≤ r holds.
As Leha is a white-hat hacker, he don't want to test this vulnerability on a real database. You are to write a similar database for Leha to test.
The first line of input contains two integers n and q (1 ≤ n ≤ 105, 1 ≤ q ≤ 105) denoting amount of cells in the bank and total amount of queries respectively.
The following line contains n integers a1, a2, ..., an (1 ≤ ai < 109) denoting the amount of money in each cell initially. These integers do not contain leading zeros.
Each of the following q lines has one of the formats:
- 1 l r x y (1 ≤ l ≤ r ≤ n, 0 ≤ x ≤ 9, 1 ≤ y ≤ 9), denoting Leha asks to change each digit x on digit y for each element ai of the sequence for which l ≤ i ≤ r holds;
- 2 l r (1 ≤ l ≤ r ≤ n), denoting you have to calculate and print the sum of elements ai for which l ≤ i ≤ r holds.
For each second type query print a single number denoting the required sum.
5 5
38 43 4 12 70
1 1 3 4 8
2 2 4
1 4 5 0 8
1 2 5 8 7
2 1 5
103
207
Let's look at the example testcase.
Initially the sequence is [38, 43, 4, 12, 70].
After the first change each digit equal to 4 becomes 8 for each element with index in interval [1; 3]. Thus, the new sequence is [38, 83, 8, 12, 70].
The answer for the first sum's query is the sum in the interval [2; 4], which equal 83 + 8 + 12 = 103, so the answer to this query is 103.
The sequence becomes [38, 83, 8, 12, 78] after the second change and [38, 73, 7, 12, 77] after the third.
The answer for the second sum's query is 38 + 73 + 7 + 12 + 77 = 207.
题意:
给你n个数
操作1:l r x y,区间[l,r]内所有数,数位上为x的都转化为y
操作2: l r 求区间和
题解:
线段树区间合并
建立10颗线段树,分别表示数字0~9所代表的值
将x转化为y也就是在将第x颗线段树区间[l,r]和减去,加到第y颗线段树上
这里的延时操作有点小技巧
每次push_down的时候保持每个点(0~9)指向唯一的另外一个点,这样再更新的时候才不会超时
#include<bits/stdc++.h>
using namespace std;
#pragma comment(linker, "/STACK:102400000,102400000")
#define ls i<<1
#define rs ls | 1
#define mid ((ll+rr)>>1)
#define pii pair<int,int>
#define MP make_pair
typedef long long LL;
const long long INF = 1e18+1LL;
const double Pi = acos(-1.0);
const int N = 5e5+, M = 1e3+, mod = 1e9+,inf = 2e9; LL sum[N][],H[N],a[N],sum2[];
int lazy[N][],vis[]; void push_down(int i,int ll,int rr) {
if(ll == rr) return ; for(int j = ; j < ; ++j) vis[j] = lazy[ls][j], sum2[j] = sum[ls][j];
for(int j = ; j < ; ++j) {
if(lazy[i][j] != j) {
for(int k = ; k < ; ++k) {
if(lazy[ls][k] == j) vis[k] = lazy[i][j];
}
sum2[lazy[i][j]] += sum[ls][j]; sum2[j] -= sum[ls][j];
}
}
for(int j = ; j < ; ++j)
lazy[ls][j] = vis[j], sum[ls][j] = sum2[j]; for(int j = ; j < ; ++j) vis[j] = lazy[rs][j], sum2[j] = sum[rs][j];
for(int j = ; j < ; ++j) {
if(lazy[i][j] != j) {
for(int k = ; k < ; ++k) {
if(lazy[rs][k] == j) vis[k] = lazy[i][j];
}sum2[lazy[i][j]] += sum[rs][j]; sum2[j] -= sum[rs][j];
}
}
for(int j = ; j < ; ++j)
lazy[rs][j] = vis[j], sum[rs][j] = sum2[j]; for(int j = ; j < ; ++j) lazy[i][j] = j;
} void push_up(int i,int ll,int rr) {
for(int j = ; j <= ; ++j) {
sum[i][j] = sum[ls][j] + sum[rs][j];
}
} void build(int i,int ll,int rr) { for(int j = ; j < ; ++j) lazy[i][j] = j; if(ll == rr) {
for(int j = ; j < ; ++j) sum[i][j] =;
LL tmp = a[ll];
for(int j = ; j <= ; ++j) {
sum[i][tmp%] += H[j-];
tmp/=;
if(tmp == ) break;
}
return ;
} build(ls,ll,mid); build(rs,mid+,rr);
push_up(i,ll,rr);
} void update(int i,int ll,int rr,int x,int y,int f,int s) { push_down(i,ll,rr);
if(ll == x && rr == y) {
for(int j = ; j <= ; ++j)
if(lazy[i][j] == f) {
lazy[i][j] = s;
sum[i][s] += sum[i][f];
sum[i][f] = ;
}
return ;
}
if(y <= mid) update(ls,ll,mid,x,y,f,s);
else if(x > mid) update(rs,mid+,rr,x,y,f,s);
else { update(ls,ll,mid,x,mid,f,s);
update(rs,mid+,rr,mid+,y,f,s); } push_up(i,ll,rr); } LL query(int i,int ll,int rr,int x,int y) {
push_down(i,ll,rr);
if(ll == x && rr == y) {
LL ret = ;
for(int j = ; j <= ; ++j) {
ret += 1LL*j*sum[i][j];
}
return ret;
}
if(y <= mid) return query(ls,ll,mid,x,y);
else if(x > mid) return query(rs,mid+,rr,x,y);
else {
return query(ls,ll,mid,x,mid)+query(rs,mid+,rr,mid+,y);
}
push_up(i,ll,rr); } int n,q; int main() { scanf("%d%d",&n,&q); for(int i = ; i <= n; ++i) {
scanf("%I64d",&a[i]);
} H[] = ;
for(int i = ; i <= ; ++i) H[i] = H[i-]*; build(,,n); for(int i = ; i <= q; ++i) {
int op,x,y,l,r;
scanf("%d",&op);
if(op == ) {
scanf("%d%d%d%d",&l,&r,&x,&y);
if(x == y) continue;
update(,,n,l,r,x,y);
}
else {
scanf("%d%d",&l,&r);
printf("%I64d\n",query(,,n,l,r));
}
} return ;
}
Codeforces 794F. Leha and security system 线段树的更多相关文章
- [Codeforces 266E]More Queries to Array...(线段树+二项式定理)
[Codeforces 266E]More Queries to Array...(线段树+二项式定理) 题面 维护一个长度为\(n\)的序列\(a\),\(m\)个操作 区间赋值为\(x\) 查询\ ...
- [Codeforces 280D]k-Maximum Subsequence Sum(线段树)
[Codeforces 280D]k-Maximum Subsequence Sum(线段树) 题面 给出一个序列,序列里面的数有正有负,有两种操作 1.单点修改 2.区间查询,在区间中选出至多k个不 ...
- codeforces 1217E E. Sum Queries? (线段树
codeforces 1217E E. Sum Queries? (线段树 传送门:https://codeforces.com/contest/1217/problem/E 题意: n个数,m次询问 ...
- Codeforces 444 C. DZY Loves Colors (线段树+剪枝)
题目链接:http://codeforces.com/contest/444/problem/C 给定一个长度为n的序列,初始时ai=i,vali=0(1≤i≤n).有两种操作: 将区间[L,R]的值 ...
- Codeforces Gym 100513F F. Ilya Muromets 线段树
F. Ilya Muromets Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100513/probl ...
- Codeforces 834D The Bakery【dp+线段树维护+lazy】
D. The Bakery time limit per test:2.5 seconds memory limit per test:256 megabytes input:standard inp ...
- codeforces 1017C - Cloud Computing 权值线段树 差分 贪心
https://codeforces.com/problemset/problem/1070/C 题意: 有很多活动,每个活动可以在天数为$[l,r]$时,提供$C$个价格为$P$的商品 现在从第一天 ...
- Codeforces 1045. A. Last chance(网络流 + 线段树优化建边)
题意 给你 \(n\) 个武器,\(m\) 个敌人,问你最多消灭多少个敌人,并输出方案. 总共有三种武器. SQL 火箭 - 能消灭给你集合中的一个敌人 \(\sum |S| \le 100000\) ...
- Codeforces 446C DZY Loves Fibonacci Numbers [线段树,数论]
洛谷 Codeforces 思路 这题知道结论就是水题,不知道就是神仙题-- 斐波那契数有这样一个性质:\(f_{n+m}=f_{n+1}f_m+f_{n}f_{m-1}\). 至于怎么证明嘛-- 即 ...
随机推荐
- CSRF verification failed. Request aborted. 表单提交方法为POST时的报错
本人所用Django版本为1.11,在设置请求方法为POST时,遇到标题中的错误,尝试了多种方法,最终通过下面的操作来修复: 在template文件中添加图中红框部分 接着,导入csrf_exempt ...
- RobotFramework:切换页面和Frame框架
切换页面主要有以下两种情况 在浏览器上打开多个窗口(Windows),在窗口内切换 打开多个浏览器(Browser),在多个浏览器内切换 1. 切换窗口 该操作适用于:打开两(多)个窗口页面,在打开的 ...
- Vim enhance part1
NO1 .认识.命令 例 删除man.config中第1到30行的注释 1.光标移到#上,按下x删除 2.按下j将光标移到第二行#上,之后按下. 3.可以看到第2行的#也被删除了因为.就是重复上次命令 ...
- java web 项目常用框架
java框架实在是太多了,网上一搜索一大箩筐,根本就了解不到什么. 我还是以我的经验来说一下j2ee的框架. 1.首先力推struts2框架,这是最经典的框架(可以说没有“之一”).可以帮你快速搭建出 ...
- 深入理解计算机操作系统——第11章:全球IP英特网
全球IP英特网 (1)每台英特网主机都运行实现TCPIP协议的软件. (2)英特网的客户端和服务器混合使用套接字接口函数和Unix IO函数来进行通信. (3)套接字函数典型的是作为陷入内核的系统调用 ...
- [洛谷U22156]未曾届到游览(矩阵树定理)
题目背景 又到了某任*堂开关中学一年一度的自主招生考试的时间了,在考试完后许多家长决定带着自己的孩子参观一下这所距千年名校还有890周年的百年学校: 题目描述 这所学校的布局非常奇怪,是一个由N 个点 ...
- (转)Redis
Rdis和JQuery一样是纯粹为应用而产生的,这里记录的是在CentOS 5.7上学习入门文章: 1.Redis简介 Redis是 一个key-value存储系统.和Memcached类似,但是解决 ...
- ORA-01034: ORACLE not available 出错
调用db.rlogon("sm/sm")出现以下错误 ORA-01034: ORACLE not availableORA-27101: shared memory realm d ...
- SpringDataJPA入门2
SpringDataJPA实体概述 JPA提供了一种简单高效的方式来管理Java对象(POJO)到关系型数据库的映射,此类Java对象成为JPA实体或简称实体.实体通常与底层数据库中的单个关系表相关联 ...
- influxDB系列(二)
来源于我在一个influxDB的qq交流群中的提问, 然后有个人 提了一个问题---->触发了我的思考!! :) 哈哈 自己的每一次说出一个回答,都是一次新的思考,也都进行了一些查阅资料,思考, ...