原題連結
題解
1.由於每個點最多修改6次,所以我們可以暴力迴圈遍歷所有點進行修改。然後可以把無需再修改的點跳過,即並查集,指向右端第一個仍然需要修改的值的下標
這樣就是單點修改加區間查詢,樹狀陣列
時間複雜度 \(6·n·log(n)\)(單點修改)+ \(m·2·log(n)\) (區間查詢)
code
#include<bits/stdc++.h>
using namespace std;
#define lowbit(x) ((x)&(-x))
int a[100005];
int fa[100005];
int tree[100005]={0};
int n;
int finds(int now){return now==fa[now]?now:fa[now]=finds(fa[now]);}
void update(int x,int val)
{
while(x<=n)
{
tree[x]+=val;
x+=lowbit(x);
}
}
int query(int x)
{
int sum=0;
while(x)
{
sum+=tree[x];
x-=lowbit(x);
}
return sum;
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
update(i,a[i]);
fa[i]=i;
}
int m;
cin>>m;
while(m--)
{
int k,l,r;
cin>>k>>l>>r;
if(l>r) swap(l,r);
if(k==0)
{
for(int i=l;i<=r&&i>=l;i=finds(i+1))
{
//printf("i:%d\n",i);
int d=sqrt(a[i]);
update(i,d-a[i]);
a[i]=d;
if(a[i]<=1) fa[i]=i+1;
}
}
else
{
cout<<query(r)-query(l-1)<<endl;
}
}
return 0;
}