Codeforces 794 F-Leha and security system[線分樹-区間更新]【データ構造】
14843 ワード
テーマリンク:http://codeforces.com/problemset/problem/794/F ————————————————————————————————F.Leha and security system time limit per test 2 seconds memory limit per test 512 megabytes inputstandard input out put put standard out Bankolis、the city you already know、finally got a new bank opened!Unfortunally、its security system is not yet working fine…Meanwhile hacker Leha arrived in Bankopolis and decided to test the system!
Bank has n cers for clients’money.A sequence from n numbers a 1,?a2,_;…,?andescribes the amount of money each clienthas.Lehants to makerequestst to the datatabase of thethe baininininininininininininininininininininininininine of of of of of of of of of babasesesestststststststststststststststststststststinininininininininininininininininininininininininininininininininininence on some subsegments.Using a bug in the system,レハcan requests two types of queries to the database:
1 l l l x x y denoting ththat Leha change s each digit x to digit y in each element of sequence ai、for which l?≦?ii?≦r r i s holds.For example、if we change i number ininberginininininininininininininininininininininininaber 11828282828282828282828282828282828282820.inininininininininininininininininininininininininininininininininininininininininininininininininindigit s in the database to 0、i.e.y.y?≠?0.2 l r denoting that Leha asks to cacacacacalate and print t he sum of such elemens of sequence a i、for which l̵?ii????̵̵?̵?̵̵̵̵̵̵?̵̵̵?̵̵̵̵̵̵simiardatabase for Leha to test.
Input The first line of input contains two integers n and q(1̵≦?nn?105,1̵̵q≦?105)denoting amount of cers thers bank bactures.
The follwing line contains n integersa 1,̵a2,̵…,?an(1?≤?ai̵)
Each of the followwing q lines has one of the formas:
1 l r x y(1̴≦?ll?≦?r?≦?n、0?≤?n、0????????̵̵̵???̵̵?̵̵̵?̵̵?;i̵≦̵rholds;2 l r(1̵≦̵l?≦r≦?n)、denoting you have to calculate and print the sum of elemens a i for which l?≦̵̵̵̵̵?̵
Examples input 5 38 43 4 12 7 1 3 4 4 8 2 4 1 4 5 0 8 1 5 5 5 8 7 2 1 5 output 103 207 input 5 5 5 5 5 6 6 6 6 9 1 3 3 2 1 2 2 1 3 1 5 5 1 1 4 4 9 2 1 5 output 111 1002 Note Let's look at the example.catese.cast。
Initially the sequence is[38,8201].
After the first change each digit equal to 4 becompes 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 103.
The sequence becompes[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のシーケンスには、二つの動作があります。は、[l,r]のすべての数のうち、ビットxをy に変更します。求[l,r]上所有数的和 問題解決の考え方:
それとも直接的な線分樹のメンテナンスを考慮して、各ノードは10個の情報を維持して、それぞれ0~9桁の和を数えて、同時に遅延標識を維持します。
求和部分略、
数桁の修正に対して、最大の問題はどのようにlazyを維持するかということです。
ここでメンテナンスしているlazyは同じ10個ありますが、lazy[i]は次の数の中でiの桁が数桁のlazy[i]になります。
問題は下に書いて伝えることです。どうすればいいですか?
普通の表記と比べて複雑ですが、息子の価値を左右するものを先に変えて、lazyを統合していくだけです。
コードを見たほうが分かりやすいです。
Bank has n cers for clients’money.A sequence from n numbers a 1,?a2,_;…,?andescribes the amount of money each clienthas.Lehants to makerequestst to the datatabase of thethe baininininininininininininininininininininininininine of of of of of of of of of babasesesestststststststststststststststststststststinininininininininininininininininininininininininininininininininininence on some subsegments.Using a bug in the system,レハcan requests two types of queries to the database:
1 l l l x x y denoting ththat Leha change s each digit x to digit y in each element of sequence ai、for which l?≦?ii?≦r r i s holds.For example、if we change i number ininberginininininininininininininininininininininininaber 11828282828282828282828282828282828282820.inininininininininininininininininininininininininininininininininininininininininininininininininindigit s in the database to 0、i.e.y.y?≠?0.2 l r denoting that Leha asks to cacacacacalate and print t he sum of such elemens of sequence a i、for which l̵?ii????̵̵?̵?̵̵̵̵̵̵?̵̵̵?̵̵̵̵̵̵simiardatabase for Leha to test.
Input The first line of input contains two integers n and q(1̵≦?nn?105,1̵̵q≦?105)denoting amount of cers thers bank bactures.
The follwing line contains n integersa 1,̵a2,̵…,?an(1?≤?ai̵)
Each of the followwing q lines has one of the formas:
1 l r x y(1̴≦?ll?≦?r?≦?n、0?≤?n、0????????̵̵̵???̵̵?̵̵̵?̵̵?;i̵≦̵rholds;2 l r(1̵≦̵l?≦r≦?n)、denoting you have to calculate and print the sum of elemens a i for which l?≦̵̵̵̵̵?̵
Examples input 5 38 43 4 12 7 1 3 4 4 8 2 4 1 4 5 0 8 1 5 5 5 8 7 2 1 5 output 103 207 input 5 5 5 5 5 6 6 6 6 9 1 3 3 2 1 2 2 1 3 1 5 5 1 1 4 4 9 2 1 5 output 111 1002 Note Let's look at the example.catese.cast。
Initially the sequence is[38,8201].
After the first change each digit equal to 4 becompes 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 103.
The sequence becompes[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のシーケンスには、二つの動作があります。
それとも直接的な線分樹のメンテナンスを考慮して、各ノードは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
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 l,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 ,l ,m,L,R,x,y);
if(R> m) update(rt<<1|1,m+1,r,L,R,x,y);
pushup(rt);
}
LL query(int rt,int l,int r,int L,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 ,l ,m,L,R);
if(R> m) ans += query(rt<<1|1,m+1,r,L,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,l,r,x,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,1,n,l,r,x,y);
}
else printf("%lld
",query(1,1,n,l,r));
}
}
return 0;
}