大致题意:

    给出两个序列A,B,A初始为负无穷,B初始为0,有三种操作

    1、在A上区间[u,v]上加一个等差数列,取与原本A序列的最大值。

    2、在B上区间[u,v]上加一个等差数列。

    3、给出一个点X,询问A[X]+B[X]的值。

    学习一个李超线段树就ojbk了,对于每次加入的等差数列,可以转化为y=a*i+b的一条线段,用李超线段树维护所有线段

    所覆盖的区间即可。数据范围比较大,线段树可以动态开点,也可以离散化。

    

 #include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
#include<set>
#include<map>
#include<stack>
#include<time.h>
#include<cstdlib>
#include<cmath>
#include<list>
using namespace std;
#define MAXN 10000006
#define eps 1e-8
#define For(i,a,b) for(int i=a;i<=b;i++)
#define Fore(i,a,b) for(int i=a;i>=b;i--)
#define lson l,mid
#define rson mid+1,r
#define mkp make_pair
#define pb push_back
#define cr clear()
#define sz size()
#define met(a,b) memset(a,b,sizeof(a))
#define iossy ios::sync_with_stdio(false)
#define fr freopen
#define pi acos(-1.0)
#define Vector Point
#define fir first
#define sec second
const long long inf=1LL<<;
const int Mod=1e9+;
typedef unsigned long long ull;
typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
inline int scan(){
int x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
struct LcSegmentTree{
ll k,b,sk,sb;
int mk;
int ls,rs;
};
ll ans1,ans2;
LcSegmentTree t[MAXN];
int tot=;
void seg1_change(int L,int R,ll a,ll b,int l,int r,int &rt){
if(!rt) {
rt=++tot;
t[rt].k=;
t[rt].b=-inf;
}
//cout<<L<<" "<<R<<" "<<a<<" "<<b<<" "<<l<<" "<<r<<" "<<rt<<" "<<t[rt].mk<<" "<<t[rt].k<<" "<<t[rt].b<<endl;
if(L==l && R==r){
bool f1=(t[rt].k*l+t[rt].b>=a*l+b),f2=(t[rt].k*r+t[rt].b>=a*r+b);
if(f1&&f2) return ;
if(!f1 && !f2) {t[rt].k=a,t[rt].b=b;return ;}
int mid=l+r>>;
bool fm=t[rt].k*mid+t[rt].b>=a*mid+b;
if(f1){
if(fm) seg1_change(mid+,R,a,b,rson,t[rt].rs);
else {
seg1_change(L,mid,t[rt].k,t[rt].b,lson,t[rt].ls);
t[rt].k=a;
t[rt].b=b;
}
}else{
if(fm) seg1_change(L,mid,a,b,lson,t[rt].ls);
else {
seg1_change(mid+,R,t[rt].k,t[rt].b,rson,t[rt].rs);
t[rt].k=a;t[rt].b=b;
}
}
return ;
}
int mid=l+r>>;
if(R<=mid) seg1_change(L,R,a,b,lson,t[rt].ls);
else if(L>mid) seg1_change(L,R,a,b,rson,t[rt].rs);
else seg1_change(L,mid,a,b,lson,t[rt].ls),seg1_change(mid+,R,a,b,rson,t[rt].rs);
}
void seg2_change(int L,int R,ll a,ll b,int l,int r,int &rt){
if(!rt) {
rt=++tot;
t[rt].k=;
t[rt].b=-inf;
}
if(L==l && R==r) {
t[rt].sk+=a;
t[rt].sb+=b;
return ;
}
int mid=l+r>>;
if(R<=mid) seg2_change(L,R,a,b,lson,t[rt].ls);
else if(L>mid) seg2_change(L,R,a,b,rson,t[rt].rs);
else seg2_change(L,mid,a,b,lson,t[rt].ls),seg2_change(mid+,R,a,b,rson,t[rt].rs);
}
void query(int xx,int l,int r,int rt){
if(!rt) return ;
ans1+=t[rt].sk*xx+t[rt].sb;
ans2=max(ans2,t[rt].k*xx+t[rt].b);
if(l==r) return ;
int mid=l+r>>;
if(xx<=mid) query(xx,lson,t[rt].ls);
else query(xx,rson,t[rt].rs);
}
int n,m,ty,u,v,ps,rot;
ll a,b;
void solve(){
met(t,);
tot=;rot=;
n=scan();m=scan();
while(m--){
ty=scan();
if(ty==) {
ps=scan();
ans1=;ans2=-inf;
query(ps,,n,rot);
if(ans2<=-inf) puts("NA");
else printf("%lld\n",ans1+ans2);
}else{
u=scan();v=scan();a=scan();b=scan();
b=b-a*u;
if(ty==) seg1_change(u,v,a,b,,n,rot);
else seg2_change(u,v,a,b,,n,rot);
}
}
}
int main(){
int t=;
while(t--) solve();
return ;
}

最新文章

  1. 使用css让div半透明
  2. Codeforces 28C [概率DP]
  3. JavaScript小知识
  4. char类型输出地址
  5. 防止 JavaScript 自动插入分号
  6. 分分钟教会大家第一个Spring入门案例
  7. C#的默认可访问性级别
  8. malloc/free vs new/delete
  9. matlab练习程序(图像马赛克)
  10. cmd下常用的一些命令
  11. C#数组的排序(正序逆序)
  12. Linux下的Shell编程
  13. 【笔记】shell下的主要工具
  14. Android中Drawable分类汇总(上)
  15. iOS WebView你需要的问题答案
  16. JDK的并发容器
  17. 用dd实现linux硬盘备份
  18. 201621123031 《Java程序设计》第12周学习总结
  19. DevOps之五 Tomcat的安装与配置
  20. Hibernate中报错org.hibernate.HibernateException: No CurrentSessionContext configured!

热门文章

  1. android获取APP 包名和activity
  2. java与Excel (.xls文件) ---使用JXL创建,增添表格文件
  3. 【leetcode 简单】 第一百一十题 分发饼干
  4. CentOs7 Python3安装Openssl以及解决ssl问题
  5. PHP在Linux下Apache环境中执行exec,system,passthru等服务器命令函数
  6. IIC串行总线的组成及其工作原理
  7. 采用dlopen、dlsym、dlclose加载动态链接库【总结】【转】
  8. .net基础初学Android
  9. linux系统iostat命令详解
  10. python网络编程--线程递归锁RLock