并查集应用
题目大意:
对一个数组多次区间更改,将该区间内的所有数字都更改为其各数码位上的数码之和。
每个位置的数的更改次数是有限的,将不能再更改的数据区间连到一个连通块内。
对于一个刚修改后不能再更改的数,将其下一个指向改为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号