Can you answer these queries?(HDU4027+势能线段树)
题目链接: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+势能线段树)的更多相关文章
- Can you answer these queries? HDU 4027 线段树
Can you answer these queries? HDU 4027 线段树 题意 是说有从1到编号的船,每个船都有自己战斗值,然后我方有一个秘密武器,可以使得从一段编号内的船的战斗值变为原来 ...
- 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 ...
- SPOJ GSS3-Can you answer these queries III-分治+线段树区间合并
Can you answer these queries III SPOJ - GSS3 这道题和洛谷的小白逛公园一样的题目. 传送门: 洛谷 P4513 小白逛公园-区间最大子段和-分治+线段树区间 ...
- 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 ...
- 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 ...
- V - Can you answer these queries? HDU - 4027 线段树 暴力
V - Can you answer these queries? HDU - 4027 这个题目开始没什么思路,因为不知道要怎么去区间更新这个开根号. 然后稍微看了一下题解,因为每一个数开根号最多开 ...
- hdu4027Can you answer these queries?【线段树】
A lot of battleships of evil are arranged in a line before the battle. Our commander decides to use ...
- 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 ...
- GSS1 - Can you answer these queries I(线段树)
前言 线段树菜鸡报告,stO ZCDHJ Orz,GSS基本上都切完了. Solution 考虑一下用线段树维护一段区间左边连续的Max,右边的连续Max,中间的连续Max还有总和,发现这些东西可以相 ...
随机推荐
- Android 布局方式学习
一.LinearLayout线性布局: 线性布局是程序中最常见的一种布局方式,线性布局可以分为水平线性布局和垂直线性布局两种, 通过android:orientation属性可以设置线性布局的方向 1 ...
- MongoDB、ElasticSearch、Redis、HBase这四种热门数据库的优缺点及应用场景
MongoDB MongoDB是当今最火爆的NoSQL数据库.MongoDB最早在09年发布,算得上是早期大数据时代的数据库代表作了.随着MongoDB的火爆,研发MongoDB的团队还专门成立了Mo ...
- C运行时库
原文地址:http://blog.csdn.net/wqvbjhc/article/details/6612099 在开发window程序是经常会遇到编译好好的程序拿到另一台机器上面无法运行的情况,这 ...
- bzoj4031-小Z的房间
题目 给一个\(n\*m\)的矩阵,每个点可能为"."或"*",有多少种方法把矩阵中的点全部连接起来,并且每两个点之间只有一条路径. 分析 题目所求的是一个矩阵 ...
- BZOJ 1898 沼泽鳄鱼(矩阵快速幂)
没有食人鱼不是裸题吗,用一个向量表示从s到1..N的距离,然后不停乘邻接矩阵行了,当然快速幂 有食人鱼,发现食人鱼最多十二个邻接矩阵一循环,处理出12个作为1个然后快速幂行了 怎么处理呢? 假设食 ...
- Go语言【第八篇】:Go语言变量作用域
Go语言变量作用域 作用域为已声明标识符所表示的常量.类型.变量.函数或包在源代码中的作用范围,Go语言中变量可以在三个地方声明: 函数内定义的变量称为局部变量: 函数外定义的变量称为全局变量: 函数 ...
- NYOJ 1000 又见斐波那契数列
描述 斐波那契数列大家应该很熟悉了吧.下面给大家引入一种新的斐波那契数列:M斐波那契数列. M斐波那契数列F[n]是一种整数数列,它的定义如下: F[0] = a F[1] = b F[n] = F[ ...
- [NOIP2012 TG D2T1]同余方程
题目大意:求关于 x 的同余方程 ax ≡ 1 (mod b)的最小正整数解. 题解:即求a在mod b意义下的逆元,这里用扩展欧几里得来解决 C++ Code: #include<cstdio ...
- 自学Python快速入门
1 helloworld#基本语法print("hello") #换行print('1221312\12312312\2312312321312\21312312') ##表示注释 ...
- B树,B+树,B*树简介
B树(有些人也叫B-树) 是一种多路搜索树 : 1.定义任意非叶子结点最多只有M个儿子:且M>2: 2.根结点的儿子数为[2, M]: 3.除根结点以外的非叶子结点的儿子数为[M/2, M]: ...