HDU-4027-Can you answer these queries?
链接:https://vjudge.net/problem/HDU-4027#author=0
题意:
给n个数,两种操作,一种对将区间内l数全部变成原来的平方根,向下取整。
一种求区间的和。
思路:
线段数,区间更新,当区间内所有数都为1时不向下更新,即segment[root] == (r - l + 1)时。
代码:
#include <iostream>
#include <memory.h>
#include <vector>
#include <map>
#include <algorithm>
#include <cstdio>
#include <math.h>
using namespace std;
typedef long long LL;
const int MAXN = 1e5 + 10;
LL segment[MAXN * 4];
LL a[MAXN];
int n, m;
int op, l, r;
void Init()
{
memset(segment, 0, sizeof(segment));
memset(a, 0, sizeof(a));
}
void Build_Tree(int root, int l, int r)
{
if (l == r)
{
segment[root] = a[l];
return;
}
int mid = (l + r) / 2;
Build_Tree(root << 1, l, mid);
Build_Tree(root << 1 | 1, mid + 1, r);
segment[root] = segment[root << 1] + segment[root << 1 | 1];
}
void Update_Tree(int root, int l, int r, int ql, int qr)
{
if (ql > r || l > qr)
return;
if (segment[root] == (r - l + 1))
return;
if (l == r)
{
segment[root] = sqrt(segment[root]);
return;
}
int mid = (l + r) / 2;
Update_Tree(root << 1, l, mid, ql, qr);
Update_Tree(root << 1 | 1, mid + 1, r, ql, qr);
segment[root] = segment[root << 1] + segment[root << 1 | 1];
}
LL Query(int root, int l, int r, int ql, int qr)
{
if (ql > r || l > qr)
return 0;
if (ql <= l && r <= qr)
return segment[root];
int mid = (l + r) / 2;
LL res = 0;
res += Query(root << 1, l, mid, ql, qr);
res += Query(root << 1 | 1, mid + 1, r, ql, qr);
return res;
}
int main()
{
int cnt = 0;
while (~scanf("%d", &n))
{
printf("Case #%d:\n", ++cnt);
for (int i = 1; i <= n; i++)
scanf("%lld", &a[i]);
scanf("%d", &m);
Build_Tree(1, 1, n);
while (m--)
{
scanf("%d%d%d", &op, &l, &r);
if (l > r)
swap(l, r);
if (op == 0)
Update_Tree(1, 1, n, l, r);
else
printf("%lld\n", Query(1, 1, n, l, r));
}
printf("\n");
}
return 0;
}

浙公网安备 33010602011771号