ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

CF794F

2022-08-17 21:34:56  阅读:125  来源: 互联网

标签:lc int tag read CF794F rg tg


\(\tt Link\)

口胡十秒钟,调题两小时。

好的其实是个不难的 \(\tt {}^{\ast}2800\)(自我安慰。


考虑线段树。节点维护十种信息代表 \(0,\cdots,9\) 的权和。

权是啥?个位权是 \(1\),十位权是 \(10\),百位权是 \(100\),以此类推。
比如 \(2627\),\(2\) 的权是 \(1010\),\(6\) 的权是 \(100\),\(7\) 的权是 \(1\)。

于是一个节点代表的区间的和,就是 \(\sum\) 数字乘上其对应权。

我们发现有了这个权和,修改可以轻松转移。

考虑原来是 \(1243\)。
\(1\) 变 \(2\),这时把 \(1\) 的权加到 \(2\) 头上
\(2\) 再变 \(4\),这时再把 \(2\) 的权加到 \(4\) 头上。
完全没有问题,权和正确

考虑一个地方的修改。

我们对于线段树的节点维护 \(tag_i\) 代表数字 \(i\) 变成了什么。

打标记:\(\forall tag_i=x,tag_i\gets y\)。

当然同时要把 \(x\) 的权和累加到 \(y\) 头上。

考虑懒标记下传。直接枚举每个 \(x\to y\) 的变换,然后修改?有问题。

比如 \(1008\),先有一次 \(1\to2\),再有一次 \(0\to1\)。
最终有 \(tag_0=1,tag_1=2\)。
直接暴力改所有 \(i\to tag_i\),这时 \(0\) 会变成 \(2\)。

所以我们在懒标记下传前,先备份当前的 \(tag\) 以及权和。

然后懒标记下传的部分相比暴力改 \(i\to tag_i\) 略有变化。

using ll = long long;

#define rep(i,a,b) for(rg int i = (a);i <= (b);++i)
#define rg register
#define il inline

const int N = 1e5 + 5,S = N << 2;

int n,m;

ll T[10][S],tmp[2][10];
char tg[10][S],old[2][10];

#define lc (i << 1)
#define rc (lc | 1)
#define mid ((L + R) >> 1)

#define ls lc,L,mid
#define rs rc,mid + 1,R
#define id rg int i = 1,rg int L = 1,rg int R = n

il void psu(int i){
	rep(d,0,9) T[d][i] = T[d][lc] + T[d][rc];
}

il void psd(rg int i){
	rep(d,0,9){
		tmp[0][d] = T[d][lc];
		tmp[1][d] = T[d][rc];
		old[0][d] = tg[d][lc];
		old[1][d] = tg[d][rc];
	}
	rep(d,0,9) if(tg[d][i] != d){
		int x = d,y = tg[d][i];
		T[y][lc] += tmp[0][x]; T[x][lc] -= tmp[0][x];
		rep(d,0,9) if(old[0][d] == x) tg[d][lc] = y;
		T[y][rc] += tmp[1][x]; T[x][rc] -= tmp[1][x];
		rep(d,0,9) if(old[1][d] == x) tg[d][rc] = y;
		tg[d][i] = d;
	}
}

il void build(id){
	rep(d,0,9) tg[d][i] = d;
	if(L == R){
		int x = read(),cur = 1;
		while(x){
			T[x % 10][i] += cur;
			x /= 10; cur *= 10;
		}
		return;
	}
	build(ls); build(rs); psu(i);
}

il void upd(rg int l,rg int r,rg int x,rg int y,id){
	if(l <= L && R <= r){
		T[y][i] += T[x][i]; T[x][i] = 0;
		rep(d,0,9) if(tg[d][i] == x) tg[d][i] = y;
		return;
	}
	psd(i);
	if(l <= mid) upd(l,r,x,y,ls);
	if(r > mid) upd(l,r,x,y,rs);
	psu(i);
}

il ll qry(rg int l,rg int r,id){
	if(l <= L && R <= r){
		ll res = 0;
		rep(d,0,9) res += T[d][i] * d;
		return res;
	}
	psd(i);
	return (l <= mid ? qry(l,r,ls) : 0LL) + (r > mid ? qry(l,r,rs) : 0LL);
}

int main(){
	n = read(),m = read();
	build();
	while(m--){
		int op = read(),l = read(),r = read();
		if(op == 2) printf("%lld\n",qry(l,r));
		else { int x = read(),y = read(); if(x != y) upd(l,r,x,y); }
	}
	return 0;
}

标签:lc,int,tag,read,CF794F,rg,tg
来源: https://www.cnblogs.com/zeno6174/p/CF794F.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有