并查集应用
题目大意:
对一个数组多次区间更改,将该区间内的所有数字都更改为其各数码位上的数码之和。
每个位置的数的更改次数是有限的,将不能再更改的数据区间连到一个连通块内。
对于一个刚修改后不能再更改的数,将其下一个指向改为ne[i]++;
并查集初始化时,要比总数据的个数n多初始化一个 ne[n+1]=n+1,避免前n个数据都变成了一块,找不到头
#include<iostream>
using namespace std;
const int N = 2e5 + 10;
int a[N],ne[N];
int find(int x)
{
return ne[x] == x ? x : ne[x] = find(ne[x]);
}
void update(int x)
{
int cnt=0;
while(a[x])
{
cnt += a[x] % 10;
a[x] /= 10;
}
a[x] = cnt;
}
int main()
{
int n, q, t;
scanf("%d", &t);
while(t--)
{
scanf("%d%d", &n, &q);
for (int i = 1; i <= n;i++) scanf("%d",&a[i]),ne[i]=i;
ne[n + 1] = n + 1;
int op, l, r;
while(q--)
{
scanf("%d%d",&op,&l);
if(op==1)
{
scanf("%d",&r);
for (int i = l; i <= r;i++)
{
i = find(i); //对每个位置,都先更新到其连通块的头部
if(i>r)
break;
update(i);
if(a[i]<10)
ne[i]++;
}
}
else
{
printf("%d\n", a[l]);
}
}
}
return 0;
}
浙公网安备 33010602011771号