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还有总和,发现这些东西可以相 ...
随机推荐
- iOS-明杰解决字段冲突,及数组映射
/** 替换关键字的属性名 */ + (NSDictionary *)mj_replacedKeyFromPropertyName{ return @{@"UUID":@" ...
- WEB安全测试要点总结
一.大类检查点: 二.测试项详细说明 上传功能 绕过文件上传检查功能 上传文件大小和次数限制 注册功能 注册请求是否安全传输 注册时密码复杂度是否后台校验 激活链接测试 重复注册 批量注册问题 登录 ...
- Stax解析XML示例代码
package org.itat.stax; import java.io.IOException; import java.io.InputStream; import javax.xml.pars ...
- BZOJ 1834 网络扩容(最大流+费用流)
对于第一问,直接求最大流. 对于第二问,建源点s和汇点t,s连1容量为INF,费用为0的边,n连t容量为最大流+k,费用为0的边.这样就把最大流限制为最多增加k了. 限制需要求扩充的最小费用,原图的边 ...
- 【bzoj5089】最大连续子段和 分块+单调栈维护凸包
题目描述 给出一个长度为 n 的序列,要求支持如下两种操作: A l r x :将 [l,r] 区间内的所有数加上 x : Q l r : 询问 [l,r] 区间的最大连续子段和. 其中,一 ...
- poj1456——Supermarket
Supermarket Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 14656 Accepted: 6656 Desc ...
- 【以前的空间】bzoj 1227 [SDOI2009]虔诚的墓主人
题解:hzw大神的博客说的很清楚嘛 http://hzwer.com/1941.html 朴素的做法就是每个点如果它不是墓地那么就可形成十字架的数量就是这个c(点左边的树的数量,k)*c(点右边的树的 ...
- 一些技巧 && 常数优化 && 出现の错误
开坑原因 7.21 今天DTZ大爷教了我一个算欧拉函数的好方法......是质因数复杂度的 这让我想到,这些小技巧小idea,很多时候,可能就是考场上最致命.最一击必杀的"大招" ...
- [BJOI2018]求和
link 其实可以用$sum(i,j)$表示从$i$到$1$的$k$次方的值,然后就是$lca$的基本操作 注意,能一起干的事情就一起搞,要不会超时 #include<iostream> ...
- Change the IPTables log file
http://www.networkinghowtos.com/howto/change-the-iptables-log-file/ An important aspect of any f ...