题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4027

题目:

题意:n个数,每次区间更新将其数值变成它的根号倍(向下取整),区间查询数值和。

思路:易知这题的lazy标记是不好打的,但是我们发现当这个数取根号直到变成1时就不需要更新了,像这种无法打标记并且经过多次操作后就不需要操作的线段树叫做势能线段树。在需要更新时我们一直暴力到它的叶子节点,当某个区间无法更新时我们将其的flag设为0,对于某个节点的flag就等于它的左右子节点的flag取或。

代码实现如下:

 #include <set>
#include <map>
#include <queue>
#include <stack>
#include <cmath>
#include <bitset>
#include <cstdio>
#include <string>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std; typedef long long ll;
typedef unsigned long long ull; #define lson i<<1,l,mid
#define rson i<<1|1,mid+1,r
#define bug printf("*********\n");
#define FIN freopen("D://code//in.txt", "r", stdin);
#define debug(x) cout<<"["<<x<<"]" <<endl;
#define IO ios::sync_with_stdio(false),cin.tie(0); const double eps = 1e-;
const int mod = 1e8;
const int maxn = 1e5 + ;
const double pi = acos(-);
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f; inline int read() {//读入挂
int ret = , c, f = ;
for(c = getchar(); !(isdigit(c) || c == '-'); c = getchar());
if(c == '-') f = -, c = getchar();
for(; isdigit(c); c = getchar()) ret = ret * + c - '';
if(f < ) ret = -ret;
return ret;
} int n, q, op, x, y; struct node {
int l, r, flag;
ll sum;
}segtree[maxn*]; void push_up(int i) {
segtree[i].sum = segtree[i*].sum + segtree[i*+].sum;
segtree[i].flag = segtree[i*].flag | segtree[i*+].flag;
} void build(int i, int l, int r) {
segtree[i].l = l, segtree[i].r = r, segtree[i].flag = ;
if(l == r) {
scanf("%lld", &segtree[i].sum);
if(segtree[i].sum <= ) segtree[i].flag = ;
return;
}
int mid = (l + r) >> ;
build(lson);
build(rson);
push_up(i);
} void update(int i, int l, int r) {
if(!segtree[i].flag) return;
if(segtree[i].l == segtree[i].r) {
if(segtree[i].flag) {
segtree[i].sum = sqrt(segtree[i].sum);
if(segtree[i].sum <= ) segtree[i].flag = ;
}
return;
}
int mid = (segtree[i].l + segtree[i].r) >> ;
if(r <= mid) {
if(segtree[i*].flag)
update(i*, l, r);
}
else if(l > mid) {
if(segtree[i*+].flag)
update(i*+, l, r);
}
else {
if(segtree[i*].flag) update(lson);
if(segtree[i*+].flag) update(rson);
}
push_up(i);
} ll query(int i, int l, int r) {
if(segtree[i].l == l && segtree[i].r == r) {
return segtree[i].sum;
}
int mid = (segtree[i].l + segtree[i].r) >> ;
if(l > mid) return query(i * + , l, r);
else if(r <= mid) return query(i * , l, r);
else return query(lson) + query(rson);
} int main() {
//FIN;
int icase = ;
while(~scanf("%d", &n)) {
build(, , n);
printf("Case #%d:\n", ++icase);
scanf("%d", &q);
while(q--) {
scanf("%d%d%d", &op, &x, &y);
int a = max(x, y), b = min(x, y);
if(op == ) {
update(, b, a);
} else {
printf("%lld\n", query(, b, a));
}
}
printf("\n");
}
return ;
}

Can you answer these queries?(HDU4027+势能线段树)的更多相关文章

  1. Can you answer these queries? HDU 4027 线段树

    Can you answer these queries? HDU 4027 线段树 题意 是说有从1到编号的船,每个船都有自己战斗值,然后我方有一个秘密武器,可以使得从一段编号内的船的战斗值变为原来 ...

  2. spoj gss2 : Can you answer these queries II 离线&&线段树

    1557. Can you answer these queries II Problem code: GSS2 Being a completist and a simplist, kid Yang ...

  3. SPOJ GSS3-Can you answer these queries III-分治+线段树区间合并

    Can you answer these queries III SPOJ - GSS3 这道题和洛谷的小白逛公园一样的题目. 传送门: 洛谷 P4513 小白逛公园-区间最大子段和-分治+线段树区间 ...

  4. SPOJ GSS2 - Can you answer these queries II(线段树 区间修改+区间查询)(后缀和)

    GSS2 - Can you answer these queries II #tree Being a completist and a simplist, kid Yang Zhe cannot ...

  5. Can you answer these queries III(线段树)

    Can you answer these queries III(luogu) Description 维护一个长度为n的序列A,进行q次询问或操作 0 x y:把Ax改为y 1 x y:询问区间[l ...

  6. V - Can you answer these queries? HDU - 4027 线段树 暴力

    V - Can you answer these queries? HDU - 4027 这个题目开始没什么思路,因为不知道要怎么去区间更新这个开根号. 然后稍微看了一下题解,因为每一个数开根号最多开 ...

  7. hdu4027Can you answer these queries?【线段树】

    A lot of battleships of evil are arranged in a line before the battle. Our commander decides to use ...

  8. 2018.10.16 spoj Can you answer these queries V(线段树)

    传送门 线段树经典题. 就是让你求左端点在[l1,r1][l1,r1][l1,r1]之间,右端点在[l2,r2][l2,r2][l2,r2]之间且满足l1≤l2,r1≤r2l1\le l2,r1 \l ...

  9. GSS1 - Can you answer these queries I(线段树)

    前言 线段树菜鸡报告,stO ZCDHJ Orz,GSS基本上都切完了. Solution 考虑一下用线段树维护一段区间左边连续的Max,右边的连续Max,中间的连续Max还有总和,发现这些东西可以相 ...

随机推荐

  1. 【week2】 词频统计第一次更新

    词频统计: 对每个功能预计时间: 功能 预计(min) 实际(min) 数据流读入 20 40 正则规范字符串 15 20 排序 30 45 输出 20 30 其他   25 词频统计psp 日期 类 ...

  2. JDK版本Java SE、Java EE、Java ME的区别

    想在win7 X64上搭建JAVA开发环境来着(只是尝试下),打开JAVA 官网下载JDK,发现好多版本懵了,百度了下找到这些版本的区别,故有了下文 1.JAVA SE Java2平台标准版(Java ...

  3. C#中Console.ReadLine()和Console.Read()有何区别?

    Console.Read 表示从控制台读取字符串,不换行. Console.ReadLine 表示从控制台读取字符串后进行换行. Console.Read() Console.ReadLine()方法 ...

  4. codesandbox

    codesandbox https://codesandbox.io https://codesandbox.io/dashboard https://codesandbox.io/dashboard ...

  5. 【Python】关于Python里面小数点精度控制的问题

    基础 浮点数是用机器上浮点数的本机双精度(64 bit)表示的.提供大约17位的精度和范围从-308到308的指数.和C语言里面的double类型相同.Python不支持32bit的单精度浮点数.如果 ...

  6. 【数据库】Sql Server 2008完全卸载方法(其他版本类似)

    本文介绍如何卸载 Microsoft SQL Server 2008的方法.当您按照本文中的步骤时,您还准备系统以便可以重新安装 SQL Server 2008版本 一.    SQL2008卸载. ...

  7. RT-thread内核之消息队列

    一.消息队列控制块:在include/rtdef.h中 #ifdef RT_USING_MESSAGEQUEUE /** * message queue structure */ struct rt_ ...

  8. Python文件对象的访问模式

  9. springboot2.0 快速集成kafka

    一.kafka搭建 参照<kafka搭建笔记> 二.版本 springboot版本 <parent> <groupId>org.springframework.bo ...

  10. [洛谷P4847]银河英雄传说V2

    题目大意:有$n(n\leqslant2\times10^5)$个序列,有$m(m\leqslant2\times10^5)$个操作,分三种: 1. $M\;x\;y:$把$x$所在的序列放在$y$所 ...