hdu 4027 Can you answer these queries?

原创 2017年01月03日 14:44:07

Problemacm.hdu.edu.cn/showproblem.php?pid=4027

题意:给一列值,每次操作要么更新都使得区间 [ left , right ] 内的每一个值都变成原来的平方根(再向下取整);要么询问区间 [ left , right ] 的值的总和。

分析:这种更新不像以前见的成段更新,因为区间内每个值的变化都不一样。

考虑到:1开方之后还是1,所以一个区间如果所有值都小于等于1(没说一定大于0…但按题意应该是吧…)的时侯就不用再往下更新。

题目说总和不超过 2^63,就算 2^64,最多开 7 次方就到 1(所以是不会太耗时的意思吧?)

Source code

#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;
const int N = 100000;

long long tree[N+7<<2], hp[N+1];
bool stop[N+7<<2]; // 为true表示不用再往下更新

void pushup(int x)
{
	tree[x] = tree[x<<1] + tree[x<<1|1];
	// 如果两个子结点都不用往下更新,那此结点也不用
	stop[x] = stop[x<<1] && stop[x<<1|1];
}

void build(int l, int r, int id)
{
	if(l == r)
	{
		tree[id] = hp[l];
		// 只要小于等于 1 就不用再往下更新
		stop[id] = hp[l] < 2LL;
		return;
	}
	int m = l + r >> 1;
	build(l, m, id<<1);
	build(m+1, r, id<<1|1);
	pushup(id);
}

void update(int ul, int ur, int l, int r, int id)
{
	if(stop[id]) return;
	if(l == r)
	{
		tree[id] = (long long)sqrt(1.0 * tree[id]);
		// 只要小于等于 1 就不用再往下更新
		stop[id] = tree[id] < 2LL;
		return;
	}
	int m = l + r >> 1;
	if(ul <= m)
		update(ul, ur, l, m, id<<1);
	if(ur > m)
		update(ul, ur, m+1, r, id<<1|1);
	pushup(id);
}

long long query(int ql, int qr, int l, int r, int id)
{
	if(ql <= l &&  r <= qr)
		return tree[id];
	if(r < ql || qr < l)
		return 0LL;
	int m = l + r >> 1;
	return query(ql, qr, l, m, id<<1) +
		query(ql, qr, m+1, r, id<<1|1);
}

int main()
{
	int n, kase = 0;
	while(~scanf("%d", &n))
	{
		for(int i = 1; i <= n; ++i)
			scanf("%I64d", hp + i);
		build(1, n, 1);
		printf("Case #%d:\n", ++kase);
		int m;
		scanf("%d", &m);
		for(int x,y,t; m--; )
		{
			scanf("%d%d%d", &t, &x, &y);
			if(x > y)
				swap(x, y);
			if(t == 1)
				printf("%I64d\n", query(x, y, 1, n, 1));
			else
				update(x, y, 1, n, 1);
		}
		putchar('\n');
	}
	return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。 举报

相关文章推荐

HDU4027-Can you answer these queries?(线段树+思路)

Can you answer these queries? Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65768/65768 K ...

hdu 4027 Can you answer these queries? 线段树

hdu 4027 Can you answer these queries? A lot of battleships of evil are arranged in a line before...

精选:深入理解 Docker 内部原理及网络配置

网络绝对是任何系统的核心,对于容器而言也是如此。Docker 作为目前最火的轻量级容器技术,有很多令人称道的功能,如 Docker 的镜像管理。然而,Docker的网络一直以来都比较薄弱,所以我们有必要深入了解Docker的网络知识,以满足更高的网络需求。

hdu4027 Can you answer these queries? 线段树

Can you answer these queries? Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65768/65768 K...

hdu 4027 Can you answer these queries?(线段树——区间更新)(思路)

Can you answer these queries?Problem Description A lot of battleships of evil are arranged in a lin...

HDU4027:Can you answer these queries?(线段树单点更新)

Problem Description A lot of battleships of evil are arranged in a line before the battle. Our comm...

hdu 4027 Can you answer these queries? 线段树区间修改区间查询

题目大意: 对线段树有两种操作,对连续一段整体开根号,对连续一段整体求和。 分析: 这里开根号数会越来越小,到1后根号1==1,不变,可以利用这一点。某段maxv 还有一种优化就是某一段max...
  • Mtrix
  • Mtrix
  • 2016-08-25 10:08
  • 127

hdu-4027 Can you answer these queries?

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4027 修改操作是把区间内的所有数开根号 区间求和操作 2  的 63 次开方6,7 根号也就变为了...

hdu 4027 Can you answer these queries?

Can you answer these queries?Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65768/65768 K (...

HDU 4027 Can you answer these queries 线段树

题意:在一场战役中,敌方有一排编号为1至n的战舰。你的指挥官有两种命令: 1.下令使用秘密武器攻击敌方战舰,每次攻击使得敌方一定范围的所有战舰的耐久度降低至原来的平方根(若平方根不为整数,那么舍去后面...
  • Tsaid
  • Tsaid
  • 2011-09-12 10:48
  • 693

hdu 4027 Can you answer these queries?

题意:给出N个数,有两个操作,一个是把每个数变成原来的数开根号,另一个是查询区间值的和。 思路:这个很明显是线段树。开始的时候我写的是成段更新,结果T了……后来仔细一想,每个数最多开了6次根号就会变成...
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)