题目链接: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. Qt窗口及控件-QTreeview/QTableView排序问题

    版权声明:若无来源注明,Techie亮博客文章均为原创. 转载请以链接形式标明本文标题和地址: 本文标题:Qt-QTreeview/QTableView排序问题     本文地址:http://tec ...

  2. Android 如何判断CPU是32位还是64位

    转自:http://blog.csdn.net/wangbaochu/article/details/47723265 1. 读取Android 的system property ("ro. ...

  3. web传参

    页面通过对象,将表单数据传送给后端,后端通过对象接收参数值,

  4. 【转载】input只改变光标的颜色 不改变字的颜色

    转载 http://www.cnblogs.com/yangAL/p/6934608.html color: red; text-shadow: 0px 0px 0px #000; -webkit-t ...

  5. 第69天:jQuery入口函数

    一.jQuery入口函数 1.$(document).ready(function(){}); 2.$(function(){}); 二.事件处理程序  1.事件源 Js方式:document.get ...

  6. [洛谷P5057][CQOI2006]简单题

    题目大意:有一个长度为$n$的$01$串,两个操作: $1\;l\;r:$把区间$[l,r]$翻转($0->1,1->0$) $2\;p:$求第$p$位是什么 题解:维护前缀异或和,树状数 ...

  7. BZOJ1053:[HAOI2007]反素数——题解

    http://www.lydsy.com/JudgeOnline/problem.php?id=1053 对于任何正整数x,其约数的个数记作g(x).例如g(1)=1.g(6)=4.如果某个正整数x满 ...

  8. BZOJ3526 [Poi2014]Card 【线段树】

    题目链接 BZOJ3526 题解 思来想去,发现很显然可以用线段树维护 每个区间保存所有合法方案的左右端点[当左端点一定是,右端点当然存最小的那个就行了] 这么整的数,\(\frac{1}{1000} ...

  9. BZOJ1911 [Apio2010]特别行动队 【斜率优化】

    1911: [Apio2010]特别行动队 Time Limit: 4 Sec  Memory Limit: 64 MB Submit: 5005  Solved: 2455 [Submit][Sta ...

  10. HDOJ(HDU).1003 Max Sum (DP)

    HDOJ(HDU).1003 Max Sum (DP) 点我挑战题目 算法学习-–动态规划初探 题意分析 给出一段数字序列,求出最大连续子段和.典型的动态规划问题. 用数组a表示存储的数字序列,sum ...