hdu 5828 Rikka with Sequence 【线段树+优化】
来源:互联网 发布:金蝶软件精斗云 编辑:程序博客网 时间:2024/05/29 14:52
链接:http://acm.hdu.edu.cn/showproblem.php?pid=5828
题意:给你n个数,q个操作,操作k,l,r,k=1时 区间[l,r]每个数加x,k=2时,区间[l,r]每个数开平方,k=3时,求区间[l,r]的和。
分析:我们知道一个数多次开平方会变成1,但是这里的1操作会使这个数的值增大,所以直接判断一个区间是否为1肯定超时。
官方题解加了个优化,就是判断一个区间内是否为一个值,因为有些区间在操作1和2下会变成一个值。
但是有一组数据把标程hack了:10万个2,3,2,3,2,3.......,10万个操作 加6,开根。
这样每个数相等的区间大小就为1了,标程T了。
我们来考虑这种数据,如果一个区间的极差>1,那么经过多次1,2操作后,最终这个区间的极差要么是0,要么是1,那么我们只要维护极差<=1的区间就好了。
后来也T了很久。。。要用读入优化和输入加到build里,G++提交。
代码:
#include<algorithm>#include<iostream>#include<cstring>#include<cstdio>#include<string>#include<vector>#include<queue>#include<cmath>#include<stack>#include<set>#include<map>#define INF 0x3f3f3f3f#define Mn 100010#define Mm 2000005#define mod 1000000007#define CLR(a,b) memset((a),(b),sizeof((a)))#define CLRS(a,b,Size) memset((a),(b),sizeof((a[0]))*(Size+1))#define CPY(a,b) memcpy ((a), (b), sizeof((a)))#pragma comment(linker, "/STACK:102400000,102400000")#define ul u<<1#define ur (u<<1)|1using namespace std;typedef long long ll;int read() { char c=getchar(); int re=0,f=1; while(c<'0'||c>'9') {if(c=='-') f=-1;c=getchar();} while(c>='0'&&c<='9') {re=re*10+c-'0';c=getchar();} return re*f;}int a[Mn];ll sum[Mn*4];ll maxx[Mn*4],minn[Mn*4];ll maxNum[Mn*4],minNum[Mn*4];ll all[Mn*4];ll lazy[Mn*4];void pushUp(int u) { sum[u]=sum[ul]+sum[ur]; maxx[u]=max(maxx[ul],maxx[ur]); minn[u]=min(minn[ul],minn[ur]); maxNum[u]=minNum[u]=0; if(maxx[u]==maxx[ul]) maxNum[u]+=maxNum[ul]; if(maxx[u]==maxx[ur]) maxNum[u]+=maxNum[ur]; if(minn[u]==minn[ul]) minNum[u]+=minNum[ul]; if(minn[u]==minn[ur]) minNum[u]+=minNum[ur];}void pushDown(int u,int l,int r) { if(all[u]) { int mid=(l+r)>>1; all[ul]=all[ur]=all[u]; sum[ul]=all[u]*(mid-l+1); sum[ur]=all[u]*(r-mid); maxx[ul]=maxx[ur]=minn[ul]=minn[ur]=all[u]; maxNum[ul]=minNum[ul]=mid-l+1; maxNum[ur]=minNum[ur]=r-mid; lazy[ul]=lazy[ur]=0; all[u]=0; } if(lazy[u]) { int mid=(l+r)>>1; lazy[ul]+=lazy[u];lazy[ur]+=lazy[u]; sum[ul]+=lazy[u]*(mid-l+1); sum[ur]+=lazy[u]*(r-mid); maxx[ul]+=lazy[u];minn[ul]+=lazy[u]; maxx[ur]+=lazy[u];minn[ur]+=lazy[u]; lazy[u]=0; }}void build(int l,int r,int u) { all[u]=lazy[u]=maxx[u]=minn[u]=sum[u]=0; if(l==r) { maxx[u]=minn[u]=sum[u]=read(); maxNum[u]=minNum[u]=1; return ; } int mid=(l+r)>>1; build(l,mid,ul); build(mid+1,r,ur); pushUp(u);}int s,t;void add(int l,int r,int u,int x) { if(s<=l&&t>=r) { sum[u]+=(ll)x*(r-l+1); minn[u]+=x; maxx[u]+=x; lazy[u]+=x; return ; } pushDown(u,l,r); int mid=(l+r)>>1; if(s<=mid) add(l,mid,ul,x); if(t>mid) add(mid+1,r,ur,x); pushUp(u);}void Sqrt(int l,int r,int u) { if(s<=l&&t>=r&&(maxx[u]-minn[u]<=1)) { if(maxx[u]==1) return ; int x=maxx[u]; if(maxx[u]==minn[u]) { minn[u]=maxx[u]=floor(sqrt(x)); lazy[u]+=maxx[u]-x; sum[u]=maxx[u]*(r-l+1); return ; } else if(maxx[u]-minn[u]==1){ maxx[u]=floor(sqrt(maxx[u])); minn[u]=floor(sqrt(minn[u])); if(maxx[u]==minn[u]) { maxNum[u]=minNum[u]=r-l+1; lazy[u]=0; all[u]=maxx[u]; sum[u]=maxx[u]*maxNum[u]; } else if(maxx[u]-minn[u]==1) { lazy[u]+=maxx[u]-x; sum[u]=maxx[u]*maxNum[u]+minn[u]*minNum[u]; } return ; } return ; } pushDown(u,l,r); int mid=(l+r)>>1; if(s<=mid) Sqrt(l,mid,ul); if(t>mid) Sqrt(mid+1,r,ur); pushUp(u);}ll query(int l,int r,int u) { if(s<=l&&t>=r) { return sum[u]; } pushDown(u,l,r); int mid=(l+r)>>1; ll re=0; if(s<=mid) re+=query(l,mid,ul); if(t>mid) re+=query(mid+1,r,ur); return re;}int main() { int T=read(),k; while(T--) { int n=read(),m=read(); build(1,n,1); while(m--) { k=read(),s=read(),t=read(); if(k==1) { int x=read(); add(1,n,1,x); } else if(k==2){ Sqrt(1,n,1); } else { printf("%I64d\n",query(1,n,1)); } } } return 0;}
0 0
- HDU 5828 Rikka with Sequence(线段树+小优化)
- hdu 5828 Rikka with Sequence 【线段树+优化】
- HDU 5828 Rikka with Sequence 线段树优化
- 2016多校8 HDU 5828 Rikka with Sequence 线段树优化
- HDU 5828 Rikka with Sequence(线段树)
- Hdu-5828 Rikka with Sequence(线段树)
- HDU-5828-Rikka with Sequence(线段树)
- 【HDU 5828】Rikka with Sequence(线段树)
- HDU 5828 Rikka with Sequence(线段树)
- 线段树,区间开方(Rikka with Sequence,HDU 5828)
- HDU 5828 Rikka with Sequence
- Hdu 5828 Rikka with Sequence
- HDU 5828 Rikka with Sequence
- HDU 5828 多校第八场 1008 Rikka with Sequence(线段树--数据加强版)
- HDU 5828-H - Rikka with Sequence-线段树+玄学-区间开方/区间更新/区间求和
- hdu5828 Rikka with Sequence(线段树)
- 【HDU5828】Rikka with Sequence(线段树)
- HDU 5828 Rikka with Sequence 解题报告
- std::map的使用方法
- 初学android-调用百度api显示地图(出现显示网格问题)
- poj3414Pots(bfs模拟数组 回溯路径)
- 第四章Response和增删改查(1)
- iOS 关闭和开启闪光灯
- hdu 5828 Rikka with Sequence 【线段树+优化】
- Ionic调用摄像头拍照和选择图库照片功能的注意点
- QueryRunner 结果处理器
- Android-ViewPagerIndicator使用方法
- 机器学习中的相似性度量
- Android开发笔记之主题背景的修改(设置Theme.NoTitleBar后Activity背景变成黑色)
- Android-----借助MINA框架实现长连接、短连接以及断线重连
- 关于checkbox全选的问题
- 打印机 针式打印机 热敏打印机