题目链接:http://codeforces.com/problemset/problem/794/F
——————————————————————————————————————
F. Leha and security system
time limit per test2 seconds
memory limit per test512 megabytes
inputstandard input
outputstandard output
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.

Input
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, 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.
Output
For each second type query print a single number denoting the required sum.

Examples
input
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
output
103
207
input
5 5
25 36 39 40 899
1 1 3 2 7
2 1 2
1 3 5 9 1
1 4 4 0 9
2 1 5
output
111
1002
Note
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, 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, 78] after the second change and [38, 73, 7, 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
  2. 求[l,r]上所有数的和

解题思路:

还是考虑直接的线段树维护,
每个节点维护10个信息,分别是数位为0~9的和,同时维护延迟标记

求和部分略,

对于数位修改,最大的问题就是考虑 如何维护lazy了,

这里维护的lazy同样有10个,lazy[i]表示的是接下来的数中数位为i的要变成数位lazy[i]

那么问题就是标记下传怎么搞了

和普通的标记下传相比 较为复杂,但也无非是把左右儿子的值先改过来,再把lazy合并过去,

还是看代码 比较好理解

这是对左儿子进行pushdown的
    for(int i=0;i<10;i++)vis[i]=lazy[rt<<1][i],sum2[i]=sum[rt<<1][i];  // 找两个临时变量代替左儿子的信息
    for(int i=0;i<10;i++)if(lazy[rt][i]!=i){                           //
        for(int j=0;j<10;j++)if(lazy[rt<<1][j]==i) vis[j]=lazy[rt][i]; //数位变化
        sum2[lazy[rt][i]]+=sum[rt<<1][i];                              // 变过去的就要加上值
        sum2[i]-=sum[rt<<1][i];                                        // 因为可能是变过来在变过去,所以不能直接赋0
    }
    for(int i=0;i<10;i++) sum[rt<<1][i]=sum2[i],lazy[rt<<1][i]=vis[i];

附本题代码
——————————————————————————————————————

#include <bits/stdc++.h>
typedef long long int LL;
using namespace std;

const int N = 1e5+7;
/*****************************************/
LL sum[N<<2][11],sum2[11],a[N];
int lazy[N<<2][11],vis[11];

void pushdown(int rt){
    for(int i=0;i<10;i++)vis[i]=lazy[rt<<1][i],sum2[i]=sum[rt<<1][i];
    for(int i=0;i<10;i++)if(lazy[rt][i]!=i){
        for(int j=0;j<10;j++)if(lazy[rt<<1][j]==i) vis[j]=lazy[rt][i];
        sum2[lazy[rt][i]]+=sum[rt<<1][i];
        sum2[i]-=sum[rt<<1][i];
    }
    for(int i=0;i<10;i++) sum[rt<<1][i]=sum2[i],lazy[rt<<1][i]=vis[i];

    for(int i=0;i<10;i++) vis[i]=lazy[rt<<1|1][i],sum2[i]=sum[rt<<1|1][i];
    for(int i=0;i<10;i++)if(lazy[rt][i]!=i){
        for(int j=0;j<10;j++)if(lazy[rt<<1|1][j]==i) vis[j]=lazy[rt][i];
        sum2[lazy[rt][i]]+=sum[rt<<1|1][i];
        sum2[i]-=sum[rt<<1|1][i];
    }
    for(int i=0;i<10;i++) sum[rt<<1|1][i]=sum2[i],lazy[rt<<1|1][i]=vis[i];

    for(int i=0;i<10;i++) lazy[rt][i] = i;
}

void pushup(int rt){
    for(int i=0;i<10;i++) sum[rt][i]=sum[rt<<1][i]+sum[rt<<1|1][i];
}

void build(int rt,int l,int r){
    for(int i=0;i<10;i++) sum[rt][i]=0;
    for(int i=0;i<10;i++)lazy[rt][i]=i;
    if(l==r){
        for(LL t=1;a[l];a[l]/=10,t*=10)
            sum[rt][a[l]%10]+=t;
        return ;
    }
    int m = r+l >> 1;
    build(rt<<1,l,m);
    build(rt<<1|1,m+1,r);
    pushup(rt);
}

void update(int rt,int r,int L,int R,int x,int y){
    if(L<=l&&r<=R){
        for(int i=0;i<10;i++)if(lazy[rt][i]==x){
            sum[rt][y]+=sum[rt][x];
            sum[rt][x]=0;
            lazy[rt][i]=y;
        }
        return ;
    }
    pushdown(rt);
    int m = r+l >> 1;
    if(L<=m) update(rt<<1,m,L,R,x,y);
    if(R> m) update(rt<<1|1,r,y);
    pushup(rt);
}

LL query(int rt,int R){
    if(L<=l&&r<=R){
        LL ans = 0;
        for(LL i=1;i<10;i++) ans+=sum[rt][i]*i;
        return ans;
    }
    pushdown(rt);
    int m = r+l >> 1;LL ans = 0;
    if(L<=m) ans += query(rt<<1,R);
    if(R> m) ans += query(rt<<1|1,R);
    pushup(rt);
    return ans;
}

int n,m;
int main(){
    while(~scanf("%d%d",&n,&m)){
        for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
        build(1,1,n);
        int op,y;
        for(int i=1;i<=m;i++){
            scanf("%d%d%d",&op,&l,&r);
            if(1==op){
                scanf("%d%d",&x,&y);
                if(x==y) continue;
                update(1,n,y);
            }
            else printf("%lld\n",query(1,r));
        }
    }
    return 0;
}

Codeforces 794F - Leha and security system [线段树-区间更新]【数据结构】的更多相关文章

  1. Java数据结构之线段树的原理与实现

    线段树是一种二叉搜索树,是用来维护区间信息的数据结构。本文将利用示例详细讲讲Java数据结构中线段树的原理与实现,需要的可以参考一下

  2. Java数据结构之线段树中的懒操作详解

    对于线段树,若要求对区间中的所有点都进行更新,可以引入懒操作。懒操作包括区间更新和区间查询操作。本文将通过一个示例和大家详细聊聊线段树中的懒操作,需要的可以参考一下

  3. POJ2823 Sliding Window(单调队列,线段树,set,deque)

    这种方法每求一个f,都要进行k-1次的比较,复杂度为O(N*k)。当然主要是i的前k-1个数中的最大值了。答案是可以,这就要用到单调递减队列。所以当index[队首元素]<i-k+1时,将队首元素删除。一般来说,deque是STL总的双端队列容器,用deque可以很方便的实现单调队列代码单调队列:set做法线段树:

  4. BZOJ 1798 [Ahoi2009] Seq 维护序列seq [线段树+多重标记下传]【数据结构】

    有长为N的数列,不妨设为a1,a2,…Input第一行两个整数N和P。第二行含有N个非负整数,从左到右依次为a1,aN,。表示把所有满足t≤i≤g的ai改为ai×c。操作2:“2tgc”。同一行相邻两数之间用一个空格隔开,每行开头和末尾没有多余空格。Output对每个操作3,按照它在输入中出现的顺序,依次输出一行一个整数表示询问结果。SampleInput7431234567512553242379313347SampleOutput2358HINT初始时数列为。对第5次操作,和为29+34+15+16=

  5. d3.js – 内联样式笔画宽度为粗体勾号

    我不使用css,因为我想保存并处理创建的SVG可视化文件.这意味着我需要使用内联样式.到目前为止,我经历了d3,因为很有可能我做错了事情.我期待{‘stroke-width’:’3px’}制作粗轴线.但它使得粗体轴标签.我希望文本被控制与字体相关的样式,如{‘font-style’:’normal’}.使用“笔画宽度”有什么问题?我在Chrome和Firefox中都进行了测试.这是我的代码:解决方法我建立在解释的答案,并更有选择地应用了行程宽度.这是我最终结论:

  6. Codeforces 794F - Leha and security system [线段树-区间更新]【数据结构】

    MeanwhilehackerLehaarrivedinBankopolisanddecidedtotestthesystem!

  7. HDU 5239 Doom [线段树,更新有上界]【数据结构】

    好久没有更新博客了更新一波吧,,,题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5239——————————————————————————————————————DoomTimeLimit:12000/6000MS(Java/Others)MemoryLimit:524288/524288K(Java/Others)TotalSubmission(

  8. 【数据结构】[BZOJ4771] 七彩树【无实现】

    Description给出一棵n个点的树,每个点有颜色多次询问以点x为根的子树中距离不超过d的点中不同颜色种类数强制在线n,m

  9. 【数据结构】【图论】[JZOJ4864] Dash Speed【无实现】

    Description给出n个点的一棵树,每条边有一个承受区间[L,R]接下来m个询问,每次询问一个x,表示需要回答所有承受区间包含x的边组成的森林的直径n,m

随机推荐

  1. 【数据结构】单调栈

    显然,每个发射站发来的能量有可能被0或1或2个其他发射站所接受,特别是为了安全,每个发射站接收到的能量总和是我们很关心的问题。由于数据很多,现只需要你帮忙计算出接收最多能量的发射站接收的能量是多少。输入输出格式输入格式:第1行:一个整数N;第2到N+1行:第i+1行有两个整数Hi和Vi,表示第i个人发射站的高度和发射的能量值。输入输出样例输入样例:34235610输出样例:7题解中有讲解代码实现

  2. BZOJ 1798 [Ahoi2009] Seq 维护序列seq [线段树+多重标记下传]【数据结构】

    有长为N的数列,不妨设为a1,a2,…Input第一行两个整数N和P。第二行含有N个非负整数,从左到右依次为a1,aN,。表示把所有满足t≤i≤g的ai改为ai×c。操作2:“2tgc”。同一行相邻两数之间用一个空格隔开,每行开头和末尾没有多余空格。Output对每个操作3,按照它在输入中出现的顺序,依次输出一行一个整数表示询问结果。SampleInput7431234567512553242379313347SampleOutput2358HINT初始时数列为。对第5次操作,和为29+34+15+16=

  3. 陈越《数据结构》第一讲 基本概念

    陈越《数据结构》第一讲基本概念1什么是数据结构1.1引子例子:如何在书架上摆放图书?数据结构是:1.数据对象在计算机中的组织方式;2.数据对象必定与一系列加在其上的操作相关联;3.完成这些操作所用的方法就是算法。抽象数据类型数据类型-数据对象集;-数据集合相关联的操作集。抽象-与存放数据的机器无关;-与数据存储的物理结构无关;-与实现操作的算法和编程语言均无关。

  4. 陈越《数据结构》第二章 线性结构

    表中元素个数称为线性表的长度;线性表没有元素时,称为空表;表起始位置称表头,表结束位置称表尾。插入和删除操作只能在链栈的栈顶进行。

  5. 【数据结构】

    非线性结构:线性结构的元素之间具有线性关系,非线性结构中的元素之间不再是序列的关系,他们呈现的是更复杂的层次关系,即一个数据元素有且仅有一个直接前驱,但可有另个或者多个直接后继,显然比序列关系复杂常见非线性结构:树,图散列表PHP中的hashtable就是哈希表就是由数组和链表组成,一个长度为16的数组中,每个元素存储的是一个链表的头结点。

  6. 【数据结构】【C++STL】FIFO队列&amp;优先队列

    首先都需要打头文件queueFIFO队列是先进先出的就好像排队一样STL定义FIFO队列优先队列的话是有优先级存在的STL定义优先队列定义方式都是大根堆FIFO队列和优先队列都有一些操作COYG

  7. 【数据结构】 堆

    自底向上://增加/减少已有节点值Heap_Increase_Key//向堆插入新的节点HeapInsert自顶向下://替换堆顶后,维持堆函数KeepHeap//弹出堆顶函数Pop

  8. 【数据结构】链表

    线性表的顺序存储结构有存储密度高及能够随机存取等优点,但存在以下不足:线性表的链式存储(单链表)的实现单向循环链表的实现

  9. 伸展树(SPLAY)个人总结+模板 [平衡树]【数据结构】【模板】

    前言最近3个月内,无论是现场赛还线上赛中SPLAY出现的概率大的惊人啊啊啊!!!然而不会的我就GG了,同时发现大家都会SPLAY,,,,然后就学习了一波。——————————————————————————-附上整体代码-md贴上来太卡了,去题解里看吧维护序列的维护一堆数的

  10. BZOJ 1895 &amp; POJ 3580 supermemo [SPLAY]【数据结构】

    Ay}Ttimes.Forexample,performing“REVOLVE242”on{1,5}INSERTxP:insertPafterAx.Forexample,performing“INSERT24”on{1,5}DELETEx:deleteAx.Forexample,performing“DELETE2”on{1,5}MINxy:querytheparticipantwhatistheminimumnumberinsub-sequence{Ax…Ay}.Forexample,thecorrec

返回
顶部