[CC-STREETTA]The Street

题目大意:

给定两个长度为\(n(n\le10^9)\)的数列\(A\)和\(B\),开始数列\(A\)中每一项值为\(-\infty\),数列\(B\)中每一项值为\(0\)。\(m(m\le3\times10^5)\)次操作,操作包含以下\(3\)种:

  1. 数列\(A\)区间加一条等差数列。
  2. 数列\(B\)区间对一个等差数列取\(\max\)。
  3. 询问\(A_i+B_i\)。

思路:

每个结点维护一个解析式\(kx+b\)。

对于数列\(A\),使用李超树维护最大值。

对于数列\(B\),直接合并两个解析式。

时间复杂度\(\mathcal O(m\log n)\)。

源代码:

#include<cstdio>
#include<cctype>
#include<climits>
#include<algorithm>
inline int getint() {
register char ch;
register bool neg=false;
while(!isdigit(ch=getchar())) neg|=ch=='-';
register int x=ch^'0';
while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
return neg?-x:x;
}
typedef long long int64;
const int SIZE=9e6;
struct Node {
int64 a,b;
void operator += (const Node &rhs) {
a+=rhs.a;
b+=rhs.b;
}
};
int64 calc(const Node &s,const int &x) {
return s.a*x+s.b;
}
class SegmentTree1 {
#define mid ((b+e)>>1)
private:
Node node[SIZE];
int left[SIZE],right[SIZE];
int sz,new_node() {
node[++sz]=(Node){0,LLONG_MIN};
return sz;
}
public:
int root;
void modify(int &p,const int &b,const int &e,const int &l,const int &r,Node s) {
p=p?:new_node();
if(b==l&&e==r) {
if(calc(node[p],b)<calc(s,b)) std::swap(node[p],s);
if(calc(node[p],e)>=calc(s,e)) return;
const double c=1.*(s.b-node[p].b)/(node[p].a-s.a);
if(c<=mid) {
modify(left[p],b,mid,b,mid,node[p]);
node[p]=s;
}
if(c>mid) modify(right[p],mid+1,e,mid+1,e,s);
return;
}
if(l<=mid) modify(left[p],b,mid,l,std::min(mid,r),s);
if(r>mid) modify(right[p],mid+1,e,std::max(mid+1,l),r,s);
}
int64 query(int &p,const int &b,const int &e,const int &x) {
p=p?:new_node();
int64 ret=calc(node[p],x);
if(b==e) return ret;
if(x<=mid) ret=std::max(ret,query(left[p],b,mid,x));
if(x>mid) ret=std::max(ret,query(right[p],mid+1,e,x));
return ret;
}
#undef mid
};
SegmentTree1 t1;
class SegmentTree2 {
#define mid ((b+e)>>1)
private:
Node node[SIZE];
int left[SIZE],right[SIZE];
int sz,new_node() {
return ++sz;
}
public:
int root;
void modify(int &p,const int &b,const int &e,const int &l,const int &r,const Node &s) {
p=p?:new_node();
if(b==l&&e==r) {
node[p]+=s;
return;
}
if(l<=mid) modify(left[p],b,mid,l,std::min(mid,r),s);
if(r>mid) modify(right[p],mid+1,e,std::max(mid+1,l),r,s);
}
int64 query(int &p,const int &b,const int &e,const int &x) {
p=p?:new_node();
int64 ret=calc(node[p],x);
if(b==e) return ret;
if(x<=mid) ret+=query(left[p],b,mid,x);
if(x>mid) ret+=query(right[p],mid+1,e,x);
return ret;
}
#undef mid
};
SegmentTree2 t2;
int main() {
const int n=getint(),m=getint();
for(register int i=0;i<m;i++) {
const int opt=getint();
if(opt==1) {
const int u=getint(),v=getint(),a=getint(),b=getint();
t1.modify(t1.root,1,n,u,v,(Node){a,b-(int64)u*a});
}
if(opt==2) {
const int u=getint(),v=getint(),a=getint(),b=getint();
t2.modify(t2.root,1,n,u,v,(Node){a,b-(int64)u*a});
}
if(opt==3) {
const int i=getint();
const int64 a=t1.query(t1.root,1,n,i),b=t2.query(t2.root,1,n,i);
if(a==LLONG_MIN) {
puts("NA");
} else {
printf("%lld\n",a+b);
}
}
}
return 0;
}

[CC-STREETTA]The Street的更多相关文章

  1. [CodeChef - STREETTA] The Street 李超线段树

    大致题意: 给出两个序列A,B,A初始为负无穷,B初始为0,有三种操作 1.在A上区间[u,v]上加一个等差数列,取与原本A序列的最大值. 2.在B上区间[u,v]上加一个等差数列. 3.给出一个点X ...

  2. hive 下篇

    由于spark on hive 问题,导致无法插入数据,暂时使用spark进行hive操作 向分区表插入数据 hive> show partitions customers;OKpartitio ...

  3. Spring -- 入门,装备集合,自动装配,分散装配,自定义编辑器

    1. 概要 struts2:web hibernate:持久化 spring:业务层.管理bean的,容器.List Map Set. 体验spring: 1.创建java项目. 2.引入spring ...

  4. Codechef March Challenge 2014——The Street

    The Street Problem Code: STREETTA https://www.codechef.com/problems/STREETTA Submit Tweet All submis ...

  5. Atitti.dw cc 2015 绿色版本安装总结

    Atitti.dw cc 2015 绿色版本安装总结 1.1. 安装程序无法初始化.请下载adobe Support Advisor检测该问题.1 1.1.1. Adobe Application M ...

  6. 【Hello CC.NET】CC.NET 实现自动化集成

    一.背景 公司的某一金融项目包含 12 个子系统,新需求一般按分支来开发,测完后合并到主干发布.开发团队需要同时维护开发环境.测试环境.模拟环境(主干).目前面临最大的两个问题: 1.子系统太多,每次 ...

  7. 浅谈iptables防SYN Flood攻击和CC攻击

    ------------------------本文为自己实践所总结,概念性的东西不全,这里粗劣提下而已,网上很多,本文主要说下目前较流行的syn洪水攻击和cc攻击------------------ ...

  8. 申请邓白氏编码的时候总是提示 Enter a valid Street Address 怎么办?

    今天要申请一个苹果开发者公司(Company)账号,然后需要邓白氏编码,然后填写企业的基本信息.其中对于Street Address认真的对照着中文翻译为如下格式: Kang Hesheng buil ...

  9. checking for fcc ....no checking for cc .. no

         源码编译,提示缺少gcc cc cl.exe 解决方案:       yum install -y gcc glibc

  10. 编译器 cc、gcc、g++、CC 的区别

    gcc 是GNU Compiler Collection,原名为Gun C语言编译器,因为它原本只能处理C语言,但gcc很快地扩展,包含很多编译器(C.C++.Objective-C.Ada.Fort ...

随机推荐

  1. 2017ACM暑期多校联合训练 - Team 8 1006 HDU 6138 Fleet of the Eternal Throne (字符串处理 AC自动机)

    题目链接 Problem Description The Eternal Fleet was built many centuries ago before the time of Valkorion ...

  2. Double类型的数向上取整和向下取整

  3. Linux下查看进程占用内存的最好方式

    今天看到stackoverflow上关于linux下如何查看某个进程占用的内存是多少的回答,觉得非常棒,不过是全英文的,很多人可能看不懂,所以我翻译一下 翻译自http://stackoverflow ...

  4. python基础===100盏灯的问题

    闪存里有人这样提问这样: 第一轮操作所有电灯,第二轮操作第2盏,第4盏开关,以此类推,第三轮改变编号为3的倍数的电灯,第3盏,第6盏,如果原来那盏灯是亮的,就熄灭它,如果原来是灭的,就点亮它,以此类推 ...

  5. (转)什么是CDC类(Communication Device Class)

    全文地址:http://justmei.blog.163.com/blog/static/1160998532010321112522467/ 什么是CDC类 (Communication Devic ...

  6. 008 BlockingQueue理解

    原文https://www.cnblogs.com/WangHaiMing/p/8798709.html 本篇将详细介绍BlockingQueue,以下是涉及的主要内容: BlockingQueue的 ...

  7. 关于Java代码优化的35条建议

    代码优化,一个很重要的课题.可能有些人觉得没用,一些细小的地方有什么好修改的,改与不改对于代码的运行效率有什么影响呢?这个问题我是这么考虑的,就像大海里面的鲸鱼一样,它吃一条小虾米有用吗?没用,但是, ...

  8. samba中的pdbedit用法

    pdbedit用于在samba服务器中创建用户: 它的用法包括 pdbedit -a username:新建Samba账户. pdbedit -x username:删除Samba账户. pdbedi ...

  9. C/C++——C语言跳出多重循环方法

    c语言的break语句只能跳出离它最近的一层循环,但是我们有时候需要跳出多层循环,以下有几种跳出多重循环的方法: 1. 使用goto ; i < MAX1; i++) { ; j < MA ...

  10. log优化

    isLoggable(Level level) 包含计算的日志记录用isLoggable判断下. debug  info warn   error   ,一般记录error,  但是其他里面的计算还是 ...