洛谷4145上帝造题的七分钟2

题目:https://www.luogu.org/problemnew/show/P4145

题解:发现1e12开方6次就变成1了。1不管开方多少次还是1。

   所以并查集记录nxt表示下一个可操作者在哪。总共操作6n次。

   树状数组维护变化值,辅以原数组前缀和,轻松出答案~

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long ll;
const int N=100005;
int n,m,l,r,nxt[N];
ll a[N],f[N],s[N];
bool b;
int find(int a)
{
    if(nxt[a]==a)return a;
    return nxt[a]=find(nxt[a]);
}
void fix(int x,ll c)
{
    if(!c)return;
    for(;x<=n;x+=(x&-x))f[x]-=c;
}
ll query(int x)
{
    ll ret=s[x];
    for(;x;x-=(x&-x))ret+=f[x];
    return ret;
}
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%lld",&a[i]);
        nxt[i]=i;s[i]=s[i-1]+a[i];
    }
    scanf("%d",&m);
    while(m--)
    {
        scanf("%d%d%d",&b,&l,&r);
        if(l>r)swap(l,r);
        if(!b)for(int i=find(nxt[l]);i<=r;i=max(i+1,find(nxt[i])))
                {
                    ll c=a[i];
                    a[i]=sqrt(a[i]);
                    fix(i,c-a[i]);
                    if(a[i]==1)nxt[i]=find(nxt[i+1]);
                }
        if(b)printf("%lld
",query(r)-query(l-1));
    }
    return 0;
}
原文地址:https://www.cnblogs.com/Narh/p/8763745.html