Codechef March Challenge 2014——The Street
Read problems statements in Mandarin Chineseand Russian.
The String street is known as the busiest street in Codeland.
Tourists from all over the world want to visit the street once they are in Codeland.
The Chef owns N souvenir stores across the street (numbered from 1 to N).
At the beginning there is no souvenir in any store, the Chef has some plans to add some new items.
Each the Chef's plan is represented by 4 numbers: u v a b which mean an items with price b
is added to the store u, an items with price a + b is added to the store u + 1 and so on.
More formally, an item with price a * i + b is added to the store u + i for all (0 ≤ i ≤ v - u).
In additional to the cost of the item itself, the tourist must pay some conservation fees as well.
The Codeland regularly defines the new conservation fee. Each fee is represented by 4 numbers: u v a b which means
the tourist buying any item in the store u + i will be charged a fee of i * a + b for all (0 ≤ i ≤ v - u).
In the case that several conservation fees have effect on the same store, the customer needs to pay all of those fees.
At some point of time, a tourist at store i asks you what is the largest amount of money they have to spend for
a souvenir at that store (the amount of money includes the price of one of the souvenirs and all the conservation fees for that store).
Input
- The first line of the input contains two integers N and M represent the number of stores and the number of events
- Each of the next M lines represents an event of three types below in the chronological order.
- The new plan of the Chef: "1 u v a b".
- The new conservation fee: "2 u v a b".
- The query from tourist: "3 i".
Output
For each query from tourist, print in one line the corresponding answer.
If there is no item at the ith store, print out "NA" (without quotes) as the answer.
Constraints
- 1 ≤ N ≤ 109
- 1 ≤ M ≤ 3*105
- For events of type 1: 1 ≤ u ≤ v ≤ N. |a|, |b| ≤ 109
- For events of type 2: 1 ≤ u ≤ v ≤ N. |a|, |b| ≤ 104
- For events of type 3: 1 ≤ i ≤ N
Example
Input:
10 10
3 5
1 3 8 3 1
3 5
1 5 10 -8 2
3 5
3 10
2 1 10 0 1
3 6
2 5 7 2 1
3 6 Output:
NA
7
7
-38
11
14 题意:
操作1:a数组的[l,r]对一个等差数列取大
操作2:给b数组的[l,r]加一个等差数列
操作3:询问 ai+bi 数据范围:10^9,所以线段树动态开点
等差数列最大值/和:一次函数
对于操作2,线段树维护a的和,b的和,当加入ax+b时,直接加上就好
对于操作1,分3种情况:
1、区间本没有等差数列,直接加上
2、区间原有的等差数列与现在的等差数列在区间内无交点,用大的直接覆盖
3、区间原有的等差数列与现在的等差数列在区间内有交点,,那么一定有一个等差数列只能对当前区间的一半区间有影响,
下传这个对一半区间有影响的等差数列,本区间保留另一个等差数列
#include<cstdio>
#include<algorithm>
#define INF (1LL<<62)
#define N 300001
using namespace std;
struct node
{
long long a,b,end;
bool have1,cross1;
bool have2,cross2;
long long maxna,maxnb;
}tr[N*];;
int n,m,lc[N*],rc[N*],tot,cnt;
int op,opl,opr,root;
long long ans1,ans2,A,B;
void flag(int k,int who,int l,int r);
long long read()
{
long long x=,f=; char c=getchar();
while(c<''||c>'') { if(c=='-') f=-; c=getchar(); }
while(c>=''&&c<='') { x=x*+c-'' ; c=getchar(); }
return x*f;
}
struct TREE
{
void add(int &k,int l,int r,long long a,long long b)
{
if(!k)
{
k=++tot;
tr[k].maxnb=-INF;
}
tr[k].cross1=true;
if(l>=opl&&r<=opr)
{
tr[k].b+=b; tr[k].a+=a;
tr[k].have1=true;
return;
}
int mid=l+r>>;
if(opl<=mid) add(lc[k],l,mid,a,b);
if(opr>mid) add(rc[k],mid+,r,a,A*(mid+-opl+-)+B);
}
double meet(long long a1,long long b1,long long a2,long long b2)
{
if(a1!=a2) return 1.0*(b2-b1)/(a1-a2);
return ;
}
void down(int &k,long long aa,long long bb,int l,int r)
{
flag(lc[k],aa,bb,l,l+r>>);
flag(rc[k],aa,aa*((l+r>>)+-l)+bb,(l+r>>)+,r);
}
void flag(int &k,long long aa,long long bb,int l,int r)
{
if(!k)
{
k=++tot;
tr[k].maxnb=-INF;
}
tr[k].cross2=true;
tr[k].have2=true;
if(l==r)
{
tr[k].maxnb=max(tr[k].maxnb,bb);
return;
}
if(!tr[k].maxna&&!tr[k].maxnb) { tr[k].maxna=aa; tr[k].maxnb=bb; return; }
long long prea=tr[k].maxna,preb=tr[k].maxnb;
long long preend=prea*(r-l+-)+preb;
long long nowend=aa*(r-l+-)+bb;
if(preb>=bb&&preend>=nowend) return;
if(preb<=bb&&preend<=nowend) { tr[k].maxna=aa; tr[k].maxnb=bb; return; }
double point=meet(tr[k].maxna,tr[k].maxnb,aa,bb);
point+=l;
if(point<1.0*(l+r>>))
{
if(preb>bb)
{
down(k,prea,preb,l,r);
tr[k].maxna=aa; tr[k].maxnb=bb;
}
else down(k,aa,bb,l,r);
}
else
{
if(preend>nowend)
{
down(k,prea,preb,l,r);
tr[k].maxna=aa; tr[k].maxnb=bb;
}
else down(k,aa,bb,l,r);
}
}
void maxn(int &k,long long aa,long long bb,int l,int r)
{
if(!k)
{
k=++tot;
tr[k].maxnb=-INF;
}
tr[k].cross2=true;
if(l>=opl&&r<=opr)
{
flag(k,aa,bb,l,r);
return;
}
if(tr[k].have2) down(k,tr[k].maxna,tr[k].maxnb,l,r);
int mid=l+r>>;
if(opl<=mid) maxn(lc[k],aa,bb,l,mid);
if(opr>mid) maxn(rc[k],aa,(mid+-opl+-)*A+B,mid+,r);
}
void query1(int k,int l,int r)
{
if(tr[k].have1) ans1+=tr[k].a*(opl-l+-)+tr[k].b;
if(!tr[lc[k]].cross1&&!tr[rc[k]].cross1) return;
int mid=l+r>>;
if(opl<=mid&&tr[lc[k]].cross1) query1(lc[k],l,mid);
else if(opl>mid&&tr[rc[k]].cross1) query1(rc[k],mid+,r);
}
void query2(int k,int l,int r)
{
if(tr[k].have2) ans2=max(ans2,tr[k].maxna*(opl-l+-)+tr[k].maxnb);
if(!tr[lc[k]].cross2&&!tr[rc[k]].cross2) return;
if(tr[k].have2) down(k,tr[k].maxna,tr[k].maxnb,l,r);
int mid=l+r>>;
if(opl<=mid&&tr[lc[k]].cross2) query2(lc[k],l,mid);
else if(opl>mid&&tr[rc[k]].cross2) query2(rc[k],mid+,r);
}
}Tree;
int main()
{
n=read(); m=read();
while(m--)
{
op=read();
if(op==)
{
opl=read(); opr=read(); A=read(); B=read();
Tree.maxn(root,A,B,,n);
}
else if(op==)
{
opl=read(); opr=read(); A=read(); B=read();
Tree.add(root,,n,A,B);
}
else
{
scanf("%d",&opl);
ans2=-INF; Tree.query2(root,,n);
if(ans2==-INF) { puts("NA"); continue; }
ans1=; Tree.query1(root,,n);
printf("%lld\n",ans1+ans2);
}
}
}
三大错误:
1、当前函数下传时,右区间首项为(mid+1-1)*a+b
mid+1时右区间第一个,再-1因为等差数列首项为 a*0+b
2、初始化:结构体内maxnb初始值为0,应该是无穷小,因为a,b可能为负数
无穷小:-2e15 会WA,直接 1LL<<62
3、down函数里下传k的等差数列后,k不能清0,因为k可能还有一个等差数列
Codechef March Challenge 2014——The Street的更多相关文章
- AC日记——The Street codechef March challenge 2014
The Street 思路: 动态开节点线段树: 等差序列求和于取大,是两个独立的子问题: 所以,建两颗线段树分开维护: 求和:等差数列的首项和公差直接相加即可: 取大: 对于线段树每个节点储存一条斜 ...
- codechef January Challenge 2014 Sereja and Graph
题目链接:http://www.codechef.com/JAN14/problems/SEAGRP [题意] 给n个点,m条边的无向图,判断是否有一种删边方案使得每个点的度恰好为1. [分析] 从结 ...
- 【分块+树状数组】codechef November Challenge 2014 .Chef and Churu
https://www.codechef.com/problems/FNCS [题意] [思路] 把n个函数分成√n块,预处理出每块中各个点(n个)被块中函数(√n个)覆盖的次数 查询时求前缀和,对于 ...
- CodeChef November Challenge 2014
重点回忆下我觉得比较有意义的题目吧.水题就只贴代码了. Distinct Characters Subsequence 水. 代码: #include <cstdio> #include ...
- 刷漆(Codechef October Challenge 2014:Remy paints the fence)
[问题描述] Czy做完了所有的回答出了所有的询问,结果是,他因为脑力消耗过大而变得更虚了:).帮助Czy恢复身材的艰巨任务落到了你的肩上. 正巧,你的花园里有一个由N块排成一条直线的木板组成的栅栏, ...
- [Codechef October Challenge 2014]刷漆
问题描述 Czy做完了所有的回答出了所有的询问,结果是,他因为脑力消耗过大而变得更虚了:).帮助Czy恢复身材的艰巨任务落到了你的肩上. 正巧,你的花园里有一个由N块排成一条直线的木板组成的栅栏,木板 ...
- Codechef December Challenge 2014 Chef and Apple Trees 水题
Chef and Apple Trees Chef loves to prepare delicious dishes. This time, Chef has decided to prepare ...
- CodeChef March Challenge 2019题解
传送门 \(CHNUM\) 显然正数一组,负数一组 for(int T=read();T;--T){ n=read(),c=d=0; fp(i,1,n)x=read(),x>0?++c:++d; ...
- CODECHEF Oct. Challenge 2014 Children Trips
@(XSY)[分塊, 倍增] Description There's a new trend among Bytelandian schools. The "Byteland Tourist ...
随机推荐
- 【Luogu1471】方差(线段树)
[Luogu1471]方差(线段树) 题面 这种傻逼题...自己去看把.. 题解 这题太傻比了 把方差公式拆开 维护平方和和区间和 修改就把平方和的公式拆开 简直傻逼的题目 #include<i ...
- 【BZOJ4538】【HNOI2016】网络(树链剖分,线段树,堆)
题目链接,我是真的懒得调题目的格式... 题解 树链剖分搞一下LCA 把线段树弄出来 这只是形式上的线段树 本质上是维护一段区间的一个堆 每次把堆插入节点, 询问的时候查询线段树上的堆的最大值就行了 ...
- MyBatis映射器元素
映射器是MyBatis最强大的工具,也是我们使用MyBatis时用的最多的工具,映射器中主要有增删改查四大元素,来满足不同场景的需要: 下面是主要元素的介绍: select:查询语句 ...
- 文件导出也可以这么写【js+blob】
文件导出在软件开发中是个比较常用的功能,基本原理也很简单: 浏览器向后台发送一个Get请求 后台处理程序接收到请求后,经过处理,返回二进制文件流 浏览器接收到二进制文件流后提示下载文件 调用的js方法 ...
- GeoJSON JS判断某一点是否在某一区域范围之内
GeoJSON JS判断某一点是否在某一区域范围之内 算法: function isInPolygon(checkPoint, polygonPoints) { var counter = 0; va ...
- Redis 桌面管理器
使用Redis桌面管理器,可以方便开发人员进行开发测试,对Redis存储内容进行可视化管理. 下载安装:https://redisdesktop.com/download 1. 为了方便测试,打开re ...
- JAVA的18条BASE
关于Java的基础知识,实践证明学习OO,最终领悟“父类控制流程,子类实现具体的业务逻辑”的OO思想,需要的不是智商而是基础,也就是说,基础越好越快领悟,所以请每位S1学习Java的学员请牢记以下Ja ...
- cxGrid_Q31584 cxgrid 拖放移动记录
cxgrid 拖放移动记录,cxgrid 拖放,cxgrid 拖动记录,cxgrid 鼠标拖动记录 这是cxgrid开发公司回复客户时所发送的源码项目,用于实现鼠标拖动记录,改变记录在表格中的位置,所 ...
- 智能合约语言 Solidity 教程系列2 - 地址类型介绍
Solidity教程系列第二篇 - Solidity地址类型介绍. 写在前面 Solidity是以太坊智能合约编程语言,阅读本文前,你应该对以太坊.智能合约有所了解,如果你还不了解,建议你先看以太坊是 ...
- 基于TODO的开发方法
之前买了一本书,叫<架构探险-从零开始写Java Web框架 >(不推荐购买-),一本标题党书籍!但是我很推崇作者写代码的方式,就是基于TODO的方式进行开发! 个人认为以基于TODO的方 ...