[HDOJ4027]Can you answer these queries?(线段树,特殊成段更新,成段查询)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4027
RT,该题要求每次更新是更新所有节点,分别求平方根,查询是求和。昨晚思前想后找有没有一个数学上的开平方的和等于和的开平方之类的规律。但是想了想发现这不就是小的时候,如果你这么想那老师就会骂死你的那个- -!
所以显然这个题是无法按套路成段更新了,懒惰标记也是没有用了,我们应该去按照区间更新每一个节点。结果TLE了一发,这说明这题不是这么搞,一定还有规律的。注意到题目给数据规模是2^63以及题目红字所述:开根号全都取下整,除了考虑用longlong以外,我们其实还可以想一下对一个longlong的数据开平方,最终都会变成1。那么在更新这个节点至1的那次update里,更新结束后一定会从叶子rt向上更新父亲,如果rt的兄弟节点也是1,那么说明rt的父亲已经不再需要更新了(因为1开平方还是1),这时候rt的父亲存的结果是1+1=2。也就是(rt+1-rt+1)。推广到更高的节点,换成区间来表示就是(r-l+1)。我们遇到这种节点就不需要更新了。
特别需要注意的是题目中x和y的大小…会出现x>y的情况……以及,每个case最后都要有一个额外的\n…………(PE到死WA到死)
#include <algorithm>
#include <iostream>
#include <iomanip>
#include <cstring>
#include <climits>
#include <complex>
#include <fstream>
#include <cassert>
#include <cstdio>
#include <bitset>
#include <vector>
#include <deque>
#include <queue>
#include <stack>
#include <ctime>
#include <set>
#include <map>
#include <cmath> using namespace std; #define fr first
#define sc second
#define pb(a) push_back(a)
#define Rint(a) scanf("%d", &a)
#define Rll(a) scanf("%I64d", &a)
#define Rs(a) scanf("%s", a)
#define FRead() freopen("in", "r", stdin)
#define FWrite() freopen("out", "w", stdout)
#define Rep(i, len) for(LL i = 0; i < (len); i++)
#define For(i, a, len) for(LL i = (a); i < (len); i++)
#define Cls(a) memset((a), 0, sizeof(a))
#define Full(a) memset((a), 0x7f7f, sizeof(a)) typedef long long LL;
#define lrt rt << 1
#define rrt rt << 1 | 1
const LL maxn = ;
LL sum[maxn<<];
LL n, q; void pushUP(LL rt) {
sum[rt] = sum[lrt] + sum[rrt];
} void build(LL l, LL r, LL rt) {
if(l == r) {
Rll(sum[rt]);
return;
}
LL m = (l + r) >> ;
build(l, m, lrt);
build(m+, r, rrt);
pushUP(rt);
} void update(LL L, LL R, LL l, LL r, LL rt) {
if(sum[rt] == r - l + ) return;
if(l == r) {
sum[rt] = LL(double(sqrt(sum[rt])));
return;
}
LL m = (l + r) >> ;
if(m >= L) update(L, R, l, m, lrt);
if(m < R) update(L,R, m+, r, rrt);
pushUP(rt);
} LL query(LL L, LL R, LL l, LL r, LL rt) {
if(l >= L && R >= r) return sum[rt];
LL m = (l + r) >> ;
LL ret = ;
if(m >= L) ret += query(L, R, l, m, lrt);
if(m < R) ret += query(L, R, m+, r, rrt);
return ret;
} int main() {
// FRead();
LL orz = ;
LL a, b, c;
while(~Rll(n)) {
Cls(sum);
printf("Case #%I64d:\n", orz++);
build(, n, );
Rll(q);
while(q--) {
Rll(a); Rll(b); Rll(c);
if(b > c) swap(b, c);
if(a == ) update(b, c, , n, );
if(a == ) cout << query(b, c, , n, ) << endl;
}
printf("\n");
}
return ;
}
[HDOJ4027]Can you answer these queries?(线段树,特殊成段更新,成段查询)的更多相关文章
- HDU4027 Can you answer these queries? —— 线段树 区间修改
题目链接:https://vjudge.net/problem/HDU-4027 A lot of battleships of evil are arranged in a line before ...
- HDU 4027 Can you answer these queries? (线段树区间修改查询)
描述 A lot of battleships of evil are arranged in a line before the battle. Our commander decides to u ...
- hdu 4027 Can you answer these queries? 线段树区间开根号,区间求和
Can you answer these queries? Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/sho ...
- HDU-4027-Can you answer these queries?线段树+区间根号+剪枝
传送门Can you answer these queries? 题意:线段树,只是区间修改变成 把每个点的值开根号: 思路:对[X,Y]的值开根号,由于最大为 263.可以观察到最多开根号7次即为1 ...
- HDU 4027 Can you answer these queries?(线段树,区间更新,区间查询)
题目 线段树 简单题意: 区间(单点?)更新,区间求和 更新是区间内的数开根号并向下取整 这道题不用延迟操作 //注意: //1:查询时的区间端点可能前面的比后面的大: //2:优化:因为每次更新都 ...
- hdu 4027 Can you answer these queries? 线段树
线段树+剪枝优化!!! 代码如下: #include<iostream> #include<stdio.h> #include<algorithm> #includ ...
- HDU4027 Can you answer these queries? 线段树
思路:http://www.cnblogs.com/gufeiyang/p/4182565.html 写写线段树 #include <stdio.h> #include <strin ...
- HDU4027 Can you answer these queries?(线段树 单点修改)
A lot of battleships of evil are arranged in a line before the battle. Our commander decides to use ...
- HDU 4027 Can you answer these queries? (线段树成段更新 && 开根操作 && 规律)
题意 : 给你N个数以及M个操作,操作分两类,第一种输入 "0 l r" 表示将区间[l,r]里的每个数都开根号.第二种输入"1 l r",表示查询区间[l,r ...
- hdu4027Can you answer these queries?(线段树)
链接 算是裸线段树了,因为没个数最多开63次 ,开到不能再看就标记.查询时,如果某段区间被标记直接返回结果,否则继续向儿子节点更新. 注意用——int64 注意L会大于R 这点我很纠结..您出题人故意 ...
随机推荐
- [转]TCP、UDP数据包大小的确定
TCP.UDP数据包大小的确定 http://blog.163.com/jianlizhao%40126/blog/static/1732511632013410101827640/ U ...
- Android keyevent 中的各个值
Android keyevent 中的各个值,在使用adb shell input 的时候用得到. 是从http://blog.csdn.net/huiguixian/article/details/ ...
- C#在Winform中改变Textbox高度三种方法
最近在做C# Winform项目,需要有一个能动态调整大小的Textbox,并且要是单行的.试了几次,单行模式的Textbox不能直接改高度.于是搜索了一下,整理出几个改变高度的方法. 1.将Text ...
- 【BZOJ】【2820】YY的GCD
莫比乌斯反演 PoPoQQQ讲义第二题. 暴力枚举每个质数,然后去更新它的倍数即可,那个g[x]看不懂就算了…… 为什么去掉了一个memset就不T了→_→…… /****************** ...
- ios开发之触摸&手势识别
概要: 4个触摸事件.6个手势识别.响应者链条 1.4个触摸事件 1> 触摸事件主要是针对视图的,包括 - (void)touchesBegan:(NSSet *)touches withEve ...
- unity3d android互调
unityPlayer = new AndroidJavaClass("com.xxx.xxx.MainActivity"); curActivity = unityPlayer. ...
- 果盟广告SDK
// // GuomobWallView.h // GuoMobWallSample // // Created by keyrun on 14-1-21. // Copyright (c) 2014 ...
- Linq to EF 与Linq to Object 使用心得
大家都知道Linq既可以用来查询数据库对象(我这里指的是Entity FrameWork里的Model对象),也可以用来查询内存中的IEnumerable对象. 两者单独查询时都不会出现什么问题,不过 ...
- First Lua function running in C
这是我在C里面跑出来的第一个Lua 文件, 纪念一下. 1.Set up envirnonment: Mac下面 Lua的src (即include) 和lib(binary)是分开的, 所以需要分别 ...
- CF 295A Greg and Array (两次建树,区间更新,单点查询)
#include <iostream> #include <stdio.h> #include <string.h> #include <algorithm& ...