# 【bzoj3211】花神游历各国 并查集+树状数组

4
1 100 5 5
5
1 1 2
2 1 2
1 1 2
2 2 3
1 1 4

101
11
11

#include <cstdio>
#include <cmath>
#include <algorithm>
#define N 100010
using namespace std;
typedef long long ll;
int n , b[N];
ll w[N] , f[N];
int find(int x)
{
return b[x] == x ? x : b[x] = find(b[x]);
}
void update(int x , ll a)
{
int i;
for(i = x ; i <= n ; i += i & -i) f[i] += a;
}
ll query(int x)
{
int i;
ll ans = 0;
for(i = x ; i ; i -= i & -i) ans += f[i];
return ans;
}
int main()
{
int m , i , opt , l , r;
ll tmp;
scanf("%d" , &n);
for(i = 1 ; i <= n ; i ++ )
scanf("%lld" , &w[i]) , b[i] = (w[i] <= 1 ? i + 1 : i) , update(i , w[i]);
b[n + 1] = n + 1;
scanf("%d" , &m);
while(m -- )
{
scanf("%d%d%d" , &opt , &l , &r);
if(opt == 1) printf("%lld\n" , query(r) - query(l - 1));
else
{
for(i = find(l) ; i <= r ; i = find(i + 1))
{
tmp = (ll)sqrt(w[i]) , update(i , tmp - w[i]) , w[i] = tmp;
if(w[i] <= 1) b[i] = find(i + 1);
}
}
}
return 0;
}

posted @ 2017-05-04 20:41  GXZlegend  阅读(353)  评论(0编辑  收藏  举报