# BZOJ 3211 弗洛拉前往国家 树阵+并检查集合

标题效果：弗洛拉看上每个国家，有时候，他会是一个连续的国家访问，求他的胃口和；有时候，他会产生厌恶国家的连续周期。喜欢成为sqrt(x)按四舍五入。

CODE：

#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define MAX 200010
using namespace std;

int src[MAX];
long long fenwick[MAX];

int father[MAX];

void Pretreatment();

inline void Fix(int x,int c);
inline void Fix(int x);
inline long long GetSum(int x);

int Find(int x);

int main()
{
cin >> cnt;
for(int i = 1;i <= cnt; ++i) {
scanf("%d",&src[i]);
Fix(i,src[i]);
if(src[i] <= 1)	father[i] = i + 1;
}
for(int flag,x,y,i = 1;i <= asks; ++i) {
scanf("%d%d%d",&flag,&x,&y);
if(flag == 1)
printf("%lld\n",GetSum(y) - GetSum(x - 1));
else
for(x = Find(x);x <= y;x = Find(x + 1)) {
Fix(x,-src[x]);
src[x] = sqrt(src[x]) + 1e-7;
Fix(x,src[x]);
if(src[x] == 1)	father[x] = Find(x + 1);
}
}
return 0;
}

inline void Fix(int x,int c)
{
for(int i = x;i <= cnt;i += i&-i)
fenwick[i] += c;
}

inline long long GetSum(int x)
{
long long re = 0;
for(int i = x;i;i -= i&-i)
re += fenwick[i];
return re;
}

int Find(int x)
{
if(!father[x] || father[x] == x)	return father[x]  = x;
return father[x] = Find(father[x]);
}


posted @ 2015-07-23 16:36  mfrbuaa  阅读(142)  评论(0编辑  收藏  举报