HDU 5828 Rikka with Sequence
好久没写线段树了,这题作为一个回味..
第一种操作的话,就是一个延迟标记。
第二种操作可以暴力更新下去,但是有一个优化,如果某区间内所有值都是一样的,或者最大值和最小值相差1,那么到此结束,不要继续往下面更新了。
这样一来的话,pushDown的时候要注意一下,如果该区间内所有值都一样,或者最大值和最小值相差1,那么延迟标记不要往下扔了,直接把该区间的信息传下去。如果该区间内所有值不一样,将延迟标记扔下去。
总体难度不算大,仔细一些就能AC。
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<iostream>
using namespace std;
typedef long long LL;
const double pi=acos(-1.0),eps=1e-;
void File()
{
freopen("D:\\in.txt","r",stdin);
freopen("D:\\out.txt","w",stdout);
}
template <class T>
inline void read(T &x) {
char c = getchar(); x = ;while(!isdigit(c)) c = getchar();
while(isdigit(c)) { x = x * + c - ''; c = getchar(); }
} const int maxn=+;
struct Seg { LL sum,f,MAX,MIN; }s[*maxn];
int T,n,m; void pushUp(int rt)
{
s[rt].sum=s[*rt].sum+s[*rt+].sum;
s[rt].MAX=max(s[*rt].MAX,s[*rt+].MAX);
s[rt].MIN=min(s[*rt].MIN,s[*rt+].MIN);
} void pushDown(int l,int r,int rt)
{
if(s[rt].MIN==s[rt].MAX)
{
s[*rt].MIN=s[*rt+].MIN=s[rt].MIN;
s[*rt].MAX=s[*rt+].MAX=s[rt].MAX; int fz=(l+r)/-l+;
s[*rt].sum=(LL)fz*s[rt].MIN;
s[*rt+].sum=s[rt].sum-s[*rt].sum;
s[rt].f=s[*rt].f=s[*rt+].f=;
return;
} if(s[rt].MIN==s[rt].MAX-)
{
int Tmin=min(s[*rt].MIN,s[*rt+].MIN),Tmax=max(s[*rt].MAX,s[*rt+].MAX); int len,x1,x2;
if(s[*rt].MIN==s[*rt].MAX)
{
if(s[*rt].MIN==Tmin) s[*rt].MIN=s[*rt].MAX=s[rt].MIN;
else s[*rt].MIN=s[*rt].MAX=s[rt].MAX;
s[*rt].sum=(LL)((l+r)/-l+)*s[*rt].MIN;
}
else
{
len=(l+r)/-l+;
x1=(s[*rt].sum-s[*rt].MAX*(LL)len)/(s[*rt].MIN-s[*rt].MAX); x2=len-x1;
s[*rt].MAX=s[rt].MAX; s[*rt].MIN=s[rt].MIN;
s[*rt].sum=(LL)x1*s[*rt].MIN+(LL)x2*s[*rt].MAX;
} if(s[*rt+].MIN==s[*rt+].MAX)
{
if(s[*rt+].MIN==Tmin) s[*rt+].MIN=s[*rt+].MAX=s[rt].MIN;
else s[*rt+].MIN=s[*rt+].MAX=s[rt].MAX;
s[*rt+].sum=(r-(l+r)/)*s[*rt+].MIN;
}
else
{
len=r-(l+r)/;
x1=(s[*rt+].sum-s[*rt+].MAX*(LL)len)/(s[*rt+].MIN-s[*rt+].MAX); x2=len-x1;
s[*rt+].MAX=s[rt].MAX; s[*rt+].MIN=s[rt].MIN;
s[*rt+].sum=(LL)x1*s[*rt+].MIN+(LL)x2*s[*rt+].MAX;
}
s[rt].f=s[*rt].f=s[*rt+].f=;
return;
} if(s[rt].f==) return; s[*rt].f=s[*rt].f+s[rt].f;
s[*rt+].f=s[*rt+].f+s[rt].f; s[*rt].MAX=s[*rt].MAX+s[rt].f;
s[*rt+].MAX=s[*rt+].MAX+s[rt].f; s[*rt].MIN=s[*rt].MIN+s[rt].f;
s[*rt+].MIN=s[*rt+].MIN+s[rt].f; int m=(l+r)/;
s[*rt].sum=s[*rt].sum+(LL)(m-l+)*s[rt].f;
s[*rt+].sum=s[*rt+].sum+(LL)(r-m)*s[rt].f; s[rt].f=;
} void build(int l,int r,int rt)
{
s[rt].f=; s[rt].MAX=; s[rt].MIN=; s[rt].sum=;
if(l==r)
{
read(s[rt].sum);
s[rt].f=; s[rt].MAX=s[rt].sum; s[rt].MIN=s[rt].sum;
return;
}
int m=(l+r)/;
build(l,m,*rt);
build(m+,r,*rt+);
pushUp(rt);
} void add(int L,int R,int x,int l,int r,int rt)
{
if(L<=l&&r<=R)
{
s[rt].f=s[rt].f+x; s[rt].MAX=s[rt].MAX+x;
s[rt].MIN=s[rt].MIN+x; s[rt].sum=s[rt].sum+(r-l+)*(LL)x;
return;
}
pushDown(l,r,rt);
int m=(l+r)/;
if(L<=m) add(L,R,x,l,m,*rt);
if(R>m) add(L,R,x,m+,r,*rt+);
pushUp(rt);
} LL quary(int L,int R,int l,int r,int rt)
{
if(L<=l&&r<=R) return s[rt].sum;
pushDown(l,r,rt);
int m=(l+r)/; LL x1=,x2=;
if(L<=m) x1=quary(L,R,l,m,*rt);
if(R>m) x2=quary(L,R,m+,r,*rt+);
pushUp(rt);
return x1+x2;
} void force(int l,int r,int rt)
{
if(l==r)
{
s[rt].sum=(LL)sqrt(1.0*s[rt].sum);
s[rt].MIN=s[rt].MAX=s[rt].sum;
return;
}
if(s[rt].MIN==s[rt].MAX)
{
s[rt].MAX=s[rt].MIN=(LL)sqrt(1.0*s[rt].MIN);
s[rt].sum=(LL)(r-l+)*s[rt].MIN;
return;
} if(s[rt].MIN==s[rt].MAX-)
{
int len=r-l+;
int x1=(s[rt].sum-s[rt].MAX*(LL)len)/(s[rt].MIN-s[rt].MAX), x2=len-x1;
s[rt].MAX=(LL)sqrt(1.0*s[rt].MAX);
s[rt].MIN=(LL)sqrt(1.0*s[rt].MIN);
s[rt].sum=(LL)x1*s[rt].MIN+(LL)x2*s[rt].MAX; return;
} pushDown(l,r,rt);
int m=(l+r)/;
if(s[*rt].MAX!=) force(l,m,*rt);
if(s[*rt+].MAX!=) force(m+,r,*rt+);
pushUp(rt);
} void update(int L,int R,int l,int r,int rt)
{
if(L<=l&&r<=R) { if(s[rt].MAX==) return; force(l,r,rt); return; }
pushDown(l,r,rt);
int m=(l+r)/;
if(L<=m&&s[*rt].MAX!=) update(L,R,l,m,*rt);
if(R>m&&s[*rt+].MAX!=) update(L,R,m+,r,*rt+);
pushUp(rt);
} int main()
{
scanf("%d",&T); while(T--)
{
read(n); read(m); build(,n,);
for(int i=;i<=m;i++)
{
int op,L,R,x;
read(op); read(L); read(R);
if(op==) { read(x); add(L,R,x,,n,); }
else if(op==) update(L,R,,n,);
else if(op==) printf("%lld\n",quary(L,R,,n,));
}
}
return ;
}
HDU 5828 Rikka with Sequence的更多相关文章
- 判断相同区间(lazy) 多校8 HDU 5828 Rikka with Sequence
// 判断相同区间(lazy) 多校8 HDU 5828 Rikka with Sequence // 题意:三种操作,1增加值,2开根,3求和 // 思路:这题与HDU 4027 和HDU 5634 ...
- HDU 5828 Rikka with Sequence (线段树)
Rikka with Sequence 题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5828 Description As we know, Rik ...
- hdu 5828 Rikka with Sequence 线段树
Rikka with Sequence 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5828 Description As we know, Rik ...
- HDU 5828 Rikka with Sequence(线段树 开根号)
Rikka with Sequence Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Othe ...
- HDU 5828 Rikka with Sequence (线段树+剪枝优化)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5828 给你n个数,三种操作.操作1是将l到r之间的数都加上x:操作2是将l到r之间的数都开方:操作3是 ...
- HDU 5828 Rikka with Sequence(线段树)
[题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=5828 [题目大意] 给出一个数列,要求支持区间加法,区间开方和区间和查询操作. [题解] 考虑开方 ...
- HDU 5828 Rikka with Sequence(线段树区间加开根求和)
Problem DescriptionAs we know, Rikka is poor at math. Yuta is worrying about this situation, so he g ...
- hdu 5204 Rikka with sequence 智商不够系列
Rikka with sequence Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.p ...
- HDU - 6087 Rikka with Sequence (可持久化treap+倍增+重构)
题目链接 感谢Dream_Lolita的题解,经过无数次失败的尝试之后终于AC了... 线段树是维护区间信息的强大工具,但它的形态是固定的,只支持修改和删除操作,不支持插入.反转.复制.分裂合并等操作 ...
随机推荐
- [Centos] mod_wsgi 安装流程以及遇到问题解决办法。apxs: command not found 或 Sorry, Python developer package does not appear to be installed.
前提: Centos 系统, apache 已安装, python 已安装. 1. 首先下载mod_wsgi-3.5.tar.gz 下载地址:https://code.google.com/p/mod ...
- 在eclipse中maven web项目部署到tomcat,访问不了
修改eclipse中tomcat发布路径后,能正常访问
- mongodb (一)
#mongodb安装(3.4.0) #下载安装包,解压 mkdir /data/mongodb cd /data/mongodb mkdir log conf data bin vim conf/mo ...
- myeclipse2014安装aptana3.4.0插件
1.下载aptana3.4.0_eclipse的zip包 http://pan.baidu.com/s/1qXOiZl6 2.打开myeclipse2014,选择help→install from ...
- [折腾纪实]JAVA的坑
开贴记录使用JAVA踩的坑-- P.S. 学习编程最好的方法就是用一个贴心的IDE写,然后隔着屏幕都能感觉到IDE在骂自己SB-- Overridable method calls in constr ...
- Golang的"泛型"模式
只要实现了Sortable接口的所有方法,就可以使用该接口的函数. 我们通过冒泡排序来演示一下: package main import "fmt" type Sortable i ...
- gulp4个基础API
Gulp.src(globs[, options]) 此接口会匹配工作目录下指定规则的文件并返回提供给下一个插件管道使用.其中globs就是匹配格式,options是一些额外参数. gulp.src( ...
- 设计模式 -- 责任链模式或者叫职责链模式(Chain of Responsibility(CoR))
什么是链?前后相连,一个连接下一个,其中包括多个节点,其实责任链模式也类似,他是多个对象之间相互关联,下一个对象的操作由上一个对象关联下来,上一个对象有个方法用于指向其他对象.职责链之间的前后关系是可 ...
- Http错误代码表
状态码 描述 100 Continue初始的请求已经接受,客户应当继续发送请求的其余部分 101 Switching Protocols服务器将遵从客户的请求转换到另外一种协议 200 OK指示请求成 ...
- L2-007. 家庭房产
L2-007. 家庭房产 题目链接:https://www.patest.cn/contests/gplt/L2-007 并查集 初学,看这题的时候完全没有什么好的想法,参考了@yinzm的blog用 ...