Can you answer these queries? HDU-4027
时间:2019-09-07
本文章向大家介绍Can you answer these queries? HDU-4027,主要包括Can you answer these queries? HDU-4027使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
题目大意是一个长度为 N (N<=1e5)的区间,区间里元素都是正整数,现在有M(M<=1e5)次区间修改与查询,区间修改的操作L,R会将[L,R]区间里面的所有元素开方(向下取整),区间查询会询问[L,R]的区间和,保证区间和小于 2^63,多组样例输入。
开始拿到这个题思路有些停滞,因为这个修改区间里每个元素的修改是不同的,而查询又是区间和,每个数字被开方到1的次数是很少的所以想从lazy标记下手存区间修改次数,查询时下推但又担心复杂度。
后来再发现通过剪枝可以很好解决复杂度的问题,就算单个元素是 2^64 大小,其被开方到1也只用6次,开始进行暴力的修改叶结点,如果在修改时发现区间和全为1就不需要再往下搜索,这样叶结点最多被访问6次,其它结点被访问最糟糕也是在单点修改的情况下:最多十七层( 0<=i <17,17为logN)而每层结点被访问的次数和都是 6*(2^i)*(N/(2^i)) ,何况单个元素小于 2^63 ,所以修改的总开销是 O(constant*NlogN),而查询仍是一次O(logN),也不会超过M次,复杂度OK。
1 #pragma optimize("O3","unroll-loops") 2 #pragma target("avx3") 3 4 #include <bits/stdc++.h> 5 using namespace std; 6 #define Lson(x) ((x)<<1) 7 #define Rson(x) ((x)<<1|1) 8 typedef long long ll; 9 const int maxn = 1e5; 10 ll raw[maxn+10]; 11 ll d[(maxn<<2)+10]; 12 13 void build(int s,int t,int p){ 14 if(s == t){ 15 d[p] = raw[s]; 16 return; 17 } 18 int mid = (s + t) >> 1; 19 build(s,mid,Lson(p)); 20 build(mid+1,t,Rson(p)); 21 d[p] = d[Lson(p)] + d[Rson(p)]; 22 } 23 24 void update(int L,int R,int s,int t,int p){ 25 // printf("%d %d %d %d\n",L,R,s,t); 26 if(d[p] <= 1ll*(t-s+1)) 27 return ; 28 if(L == s && t == R && d[p] == (t-s+1)) 29 return ; 30 if(s == t){ 31 d[p] = sqrt(d[p]); 32 return ; 33 } 34 int mid = (s + t) >> 1; 35 if(R<=mid) update(L,R,s,mid,Lson(p)); 36 else if(L > mid) update(L,R,mid+1,t,Rson(p)); 37 else update(L,mid,s,mid,Lson(p)) , update(mid+1,R,mid+1,t,Rson(p)); 38 d[p] = d[Lson(p)] + d[Rson(p)]; 39 } 40 41 ll query(int L,int R,int s,int t,int p){ 42 if(L == s && t == R){ 43 return d[p]; 44 } 45 int mid = (s + t) >> 1; 46 ll sum = 0; 47 if(R<=mid) sum += query(L,R,s,mid,Lson(p)); 48 else if(L > mid) sum += query(L,R,mid+1,t,Rson(p)); 49 else sum = query(L,mid,s,mid,Lson(p)) + query(mid+1,R,mid+1,t,Rson(p)); 50 return sum; 51 } 52 53 int main(){ 54 // __clock_t stt = clock(); 55 int cntcase =0 ; 56 int N; 57 while(scanf("%d",&N)==1){ 58 for(int i=1;i<=N;++i){ 59 scanf("%lld",&raw[i]); 60 } 61 build(1,N,1); 62 63 int M; 64 scanf("%d",&M); 65 cntcase ++; 66 printf("Case #%d:\n",cntcase); 67 for(int i=0;i<M;++i){ 68 int op,L,R; 69 scanf("%d%d%d",&op,&L,&R); 70 if(L>R) swap(L,R); 71 if(op) 72 printf("%lld\n",query(L,R,1,N,1)); 73 else 74 update(L,R,1,N,1); 75 // for(int j=1;j<=N;++j) 76 // printf("%lld%c",query(j,j,1,N,1),j==N?'\n':' '); 77 } 78 printf("\n"); 79 } 80 // __clock_t edt = clock(); 81 // printf("Used Time : %.3lfms\n", static_cast<double>(edt - stt)/1000); 82 return 0; 83 }
这题坑的地方还有一个,就是给出的区间并不是 L <= R 的需要判断一下swap ,因为这个TLE了好几次,还怀疑自己复杂度出问题了用随机大数据测了好几回,最后才发现题目Input里没做L,R的大小限制。通过这道题倒是让我觉得线段树和搜索在本质上有一定的相似。
原文地址:https://www.cnblogs.com/Kiritsugu/p/11479609.html
- jquery 操作ajax 相关方法
- SQL SERVER 2008 Hierarchyid数据类型
- Html5 学习利器 Web Standards Update for Microsoft Visual Studio 2010 SP1
- MongoDB 客户端 MongoVue
- HttpClient介绍
- 10个使用 Foundation 框架开发的WordPress 主题推荐
- jQuery 效果使用
- 几款更换WordPress 后台UI 的插件推荐
- 入门:构建简单的Web API
- WordPress 编辑器快捷键——让写作来得更方便些吧!
- ASP.NET Web API: 宿主(Hosting)
- 在 Windows Phone上使用QQConnect OAuth2
- WordPress 开发之使用WordPress 3.8+后台图标(dashicons)
- 基础(二)
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法