题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4027
题目大意:区间求平方根,求区间和
算法:线段树
思路:更新到底
注意:考虑求和的x > y的情况
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
#define lson l,m, rt << 1
#define rson m+1, r, rt << 1 | 1
#define mid int m= (l+r) >> 1
int vis[898989];
__int64 cnt[898989];
void build(int l,int r, int rt)
{
if(l == r)
{
scanf("%I64d", &cnt[rt]);
if(cnt[rt] == 0 || cnt[rt] == 1)
vis[rt] = 1;
return ;
}
mid ;
build(lson);
build(rson);
cnt[rt] = cnt[rt << 1] + cnt[rt << 1 | 1];
}
void update(int L, int R, int l, int r, int rt)
{
if(vis[rt])
return ;
if(l == r)
{
cnt[rt] = sqrt(cnt[rt]);
if(cnt[rt] == 1)
vis[rt] = 1;
return ;
}
mid ;
if(L <= m)
update(L, R, lson);
if(m < R) update(L, R, rson);
cnt[rt] = cnt[rt << 1] + cnt[rt << 1 | 1];
vis[rt] = vis[rt << 1] && vis[rt << 1 | 1];
}
__int64 query(int L, int R, int l, int r, int rt)
{
if(L <= l && r <= R)
{
return cnt[rt];
}
mid ;
__int64 ret = 0;
if(L <= m)
ret += query(L, R, lson);
if(m < R)
ret += query(L, R, rson);
return ret ;
}
int main()
{
int n, T;
int ica = 1;
while(scanf("%d", &n) != EOF)
{
printf("Case #%d:\n", ica ++);
memset(vis, 0, sizeof(vis));
memset(cnt, 0, sizeof(cnt));
build(1, n, 1);
int op;
int a, b, m;
scanf("%d", &m);
while(m --)
{
scanf("%d", &op);
scanf("%d%d", &a, &b);
if(b < a )
{
int t = a;
a = b;
b = t;
}
if(op == 1)
printf("%I64d\n", query(a, b ,1, n, 1));
else
update(a, b, 1, n, 1);
}
printf("\n");
}
return 0;
}