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
- 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
- 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.
InputThe 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.
Examples input5 5output
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
103Note
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+10, M = 1e3+20, mod = 1e9+7,inf = 2e9; LL sum[N][11],H[N],a[N],sum2[12]; int lazy[N][11],vis[12]; void push_down(int i,int ll,int rr) { if(ll == rr) return ; for(int j = 0; j < 10; ++j) vis[j] = lazy[ls][j], sum2[j] = sum[ls][j]; for(int j = 0; j < 10; ++j) { if(lazy[i][j] != j) { for(int k = 0; k < 10; ++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 = 0; j < 10; ++j) lazy[ls][j] = vis[j], sum[ls][j] = sum2[j]; for(int j = 0; j < 10; ++j) vis[j] = lazy[rs][j], sum2[j] = sum[rs][j]; for(int j = 0; j < 10; ++j) { if(lazy[i][j] != j) { for(int k = 0; k < 10; ++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 = 0; j < 10; ++j) lazy[rs][j] = vis[j], sum[rs][j] = sum2[j]; for(int j = 0; j < 10; ++j) lazy[i][j] = j; } void push_up(int i,int ll,int rr) { for(int j = 0; j <= 9; ++j) { sum[i][j] = sum[ls][j] + sum[rs][j]; } } void build(int i,int ll,int rr) { for(int j = 0; j < 10; ++j) lazy[i][j] = j; if(ll == rr) { for(int j = 0; j < 10; ++j) sum[i][j] =0; LL tmp = a[ll]; for(int j = 1; j <= 12; ++j) { sum[i][tmp%10] += H[j-1]; tmp/=10; if(tmp == 0) break; } return ; } build(ls,ll,mid); build(rs,mid+1,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 = 0; j <= 9; ++j) if(lazy[i][j] == f) { lazy[i][j] = s; sum[i][s] += sum[i][f]; sum[i][f] = 0; } return ; } if(y <= mid) update(ls,ll,mid,x,y,f,s); else if(x > mid) update(rs,mid+1,rr,x,y,f,s); else { update(ls,ll,mid,x,mid,f,s); update(rs,mid+1,rr,mid+1,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 = 0; for(int j = 1; j <= 9; ++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+1,rr,x,y); else { return query(ls,ll,mid,x,mid)+query(rs,mid+1,rr,mid+1,y); } push_up(i,ll,rr); } int n,q; int main() { scanf("%d%d",&n,&q); for(int i = 1; i <= n; ++i) { scanf("%I64d",&a[i]); } H[0] = 1; for(int i = 1; i <= 13; ++i) H[i] = H[i-1]*10; build(1,1,n); for(int i = 1; i <= q; ++i) { int op,x,y,l,r; scanf("%d",&op); if(op == 1) { scanf("%d%d%d%d",&l,&r,&x,&y); if(x == y) continue; update(1,1,n,l,r,x,y); } else { scanf("%d%d",&l,&r); printf("%I64d\n",query(1,1,n,l,r)); } } return 0; }
Codeforces 794F. Leha and security system 線段樹