考试的时候没有注意到可以将(a,b)放在二维平面上之后旋转坐标系,使得转移变成树状数组二维偏序

这样就算我想出来了第二个转移的斜率优化也没有什么卵用啊(摔西瓜

设g(i)表示当前站在第i个水果下面且第i个水果此时并没有记分的最大得分

设f(i)表示当前站在第i个水果下面且第i个水果此时已经记分的最大得分

g(i)=max(f(j)) (满足j能到达i)

f(i)=max(g(j)+(i-j+1)^2)(满足从i出发可以一路接水果走到j)

首先考虑g(i)的转移,我们注意到j能到达i当且仅当

abs(ai-aj)<=bi-bj

又注意到bi>=bj

我们对绝对值进行分类讨论后可以得到j可以到达的i都在j的10点半钟方向到13点半钟方向

之后我们将坐标系旋转,即将每个点的坐标变为(bi+ai,bi-ai)

那么j能到达的i都在j的右上方啦,那么对于这个转移就变成了一个二维偏序问题

对于一维排序,另一维用树状数组维护即可,时间复杂度O(nlogn)

之后我们考虑f(i)的转移,我们很容易发现这是可以分段的

对于每个i不能到达i+1分一段,那么这个转移每一段都是相互独立的

我们又惊奇的发现在第一个转移排序后,每一段内的相对顺序是不变的

注意到这是一个很经典的可以用斜率优化的式子

化简完后f(i)=max(g(j)-2*j+j*j-2*i*j)+(i+1)^2

对于斜率2*i,我们用很容易发现这个斜率是递增的

我们可以对于每一段用单调栈维护一个上凸包,这样这个转移就是O(n)的了

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std; typedef long long LL;
const int maxn=500010;
int n,cnt;
int a[maxn],b[maxn];
int pos[maxn];
LL dp[maxn];
LL t[maxn];
LL m1,m2,ans;
struct Point{
LL x,y,id;
Point(LL x=0,LL y=0,LL id=0):x(x),y(y),id(id){}
}p[maxn];
vector<Point>V[maxn];
int top[maxn];
typedef Point Vector;
Vector operator -(const Point &A,const Point &B){return Vector(A.x-B.x,A.y-B.y);}
LL Cross(const Vector &A,const Vector &B){return A.x*B.y-A.y*B.x;}
bool cmpy(const Point &A,const Point &B){return A.y<B.y;}
bool cmpx(const Point &A,const Point &B){
if(A.x==B.x&&A.y==B.y)return A.id<B.id;
if(A.x==B.x)return A.y<B.y;
return A.x<B.x;
}
void read(int &num){
num=0;char ch=getchar();
while(ch<'!')ch=getchar();
while(ch>='0'&&ch<='9')num=num*10+ch-'0',ch=getchar();
}
int lowbit(int x){return x&(-x);}
void modify(int x,LL v){for(int i=x;i<=cnt;i+=lowbit(i))t[i]=max(t[i],v);}
LL ask(int x){
LL mx=0;
for(int i=x;i>=1;i-=lowbit(i))mx=max(mx,t[i]);
return mx;
}
LL Get_ans(int id,LL k){
while(V[id].size()>1&&V[id][top[id]].y-2*k*V[id][top[id]].x<=V[id][top[id]-1].y-2*k*V[id][top[id]-1].x)top[id]--,V[id].pop_back();
if(!V[id].empty())return V[id][top[id]].y-2*k*V[id][top[id]].x+(k+1)*(k+1);
else return 0;
}
void push(int id,Point P){
while(V[id].size()>1&&Cross(P-V[id][top[id]],V[id][top[id]]-V[id][top[id]-1])<=0)top[id]--,V[id].pop_back();
top[id]++;V[id].push_back(P);
} int main(){
read(n);
for(int i=1;i<=n;++i){
read(a[i]);read(b[i]);
p[i]=Point(b[i]+a[i],b[i]-a[i],i);
}
for(int i=1;i<=n;++i){
if(i==1||abs(a[i]-a[i-1])>b[i]-b[i-1])pos[i]=pos[i-1]+1;
else pos[i]=pos[i-1];
}
for(int i=1;i<=n;++i)a[i]=b[i]-a[i];
sort(a+1,a+n+1);sort(p+1,p+n+1,cmpy);
for(int i=1;i<=n;++i){
if(i==1||a[i]!=a[i-1])p[i].y=++cnt;
else p[i].y=cnt;
}
sort(p+1,p+n+1,cmpx);
memset(top,-1,sizeof(top));
for(int i=1;i<=n;++i){
m1=ask(p[i].y);m2=Get_ans(pos[p[i].id],p[i].id);
dp[p[i].id]=max(m1+1,m2);
ans=max(dp[p[i].id],ans);
modify(p[i].y,dp[p[i].id]);
push(pos[p[i].id],Point(p[i].id,m1-2*p[i].id+p[i].id*p[i].id));
}printf("%lld\n",ans);
return 0;
}

  

UR #13 Ernd的更多相关文章

  1. uoj#187. 【UR #13】Ernd

    http://uoj.ac/problem/187 每个点只能从时间,b+a,b-a三维都不大于它的点转移过来,将点按时间分成尽量少的一些段,每段内三维同时非严格单调,每段内的点可能因为连续选一段而产 ...

  2. UR #13 Yist

    第一次打UR,打了一个半小时就弃疗了QAQ 这是我唯一一道考试的时候做出来的题目,其他两道连暴力都懒得写了 很容易发现对于每个要删除的点 我们找到左边第一个比他小的不用删除的点,右边第一个比他小的不用 ...

  3. UR#13 SRAND

    总感觉这位大仙讲的很清楚:bztminamoto 题意 题目讲的是求 l~r 内所有数的次大质因子,这里设 f(x) 为 x 的次大质因子 我们差分一下就变成求两个前缀和信息了 按照套路,我们考虑 S ...

  4. uoj#188. 【UR #13】Sanrd(Min_25筛)

    题面 传送门 题解 这是一道语文题 不难看出,题目所求即为\(l\)到\(r\)中每个数的次大质因子 我们考虑\(Min\_25\)筛的过程,设 \[S(n,j)=\sum_{i=1}^nsec_p( ...

  5. UOJ 188 【UR #13】Sanrd——min_25筛

    题目:http://uoj.ac/problem/188 令 \( s(n,j)=\sum\limits_{i=1}^{n}[min_i>=p_j]f(j) \) ,其中 \( min_i \) ...

  6. UOJ #188. 【UR #13】Sanrd

    Description 给定 \(\sum_{i=l}^r f[i]\) \(f[i]=\) 把 \(i\) 的每一个质因子都从小到大排列成一个序列(\(p_i^{c_i}\)要出现 \(c_i\) ...

  7. UOJ188. 【UR #13】Sanrd

    传送门 Sol 设 \(f_i\) 表示 \(i\) 的次大质因子 题目就是要求 \[\sum_{i=l}^{r}f_i\] 考虑求 \(\sum_{i=1}^{n}f_i\) 所求的东西和质因子有关 ...

  8. 「uoj#188. 【UR #13】Sanrd」

    题目 不是很能看懂题意,其实就是求\([l,r]\)区间内所有数的次大质因子的和 这可真是看起来有点鬼畜啊 这显然不是一个积性函数啊,不要考虑什么特殊的函数了 我们考虑Min_25筛的过程 设\(S( ...

  9. UOJ188. 【UR #13】Sanrd [min_25筛]

    传送门 思路 也可以算是一个板题了吧qwq 考虑min_25筛最后递归(也就是DP)的过程,要枚举当前最小的质因子是多少. 那么可以分类讨论,考虑现在这个质因子是否就是次大质因子. 如果不是,那么就是 ...

随机推荐

  1. OC7_复合类内存管理(setter方法)

    // // Person.h // OC7_复合类内存管理(setter方法) // // Created by zhangxueming on 15/6/18. // Copyright (c) 2 ...

  2. makefile--编码修改-空格出现错误

    "makefile", line 40: make: 1254-055 Dependency line needs colon or double colon operator. ...

  3. SAP第一轮面试之英语群面

    很高兴通过了SAP的笔试,昨天进行了一轮面试.SAP一轮面试是英语群面(无领导小组讨论) 面试提前大约五天的样子通知面试时间地点,一般是在公司,要求正装.这些都会在HR联系你时通知的,所以不再啰嗦. ...

  4. java线程安全和线程同步

    第一部分 线程安全(1)——变量安全 http://blog.csdn.net/cuiran/article/details/6150357 第二部分 线程安全(2)——ThreadLocal变量 h ...

  5. 如何使用C#操作快捷方式(获取快捷方式属性、创建快捷方式)

    近来项目中有需要用到一个技术:使用C#操控快捷方式,包含创建和读取等.现整理一下实现方式,分享给大家. 第一步  创建一个项目 无需废话,跳过. 第二步  引用COM组件 右键“引用”,“添加引用”, ...

  6. linux命令 chattr超级权限控件

    linux命令:chattr 1.作用 修改ext2和ext3文件系统属性(attribute),使用权限超级用户.   linux命令:chattr 1.作用修改ext2和ext3文件系统属性(at ...

  7. 百度地图API实现多区域标记

    最近遇到一个业务就是需要需要在地图上标记多个区域.一般餐饮业做外卖的,配送范围一般是多区域的,那么在地图上标记配送范围的时候就需要能标记多个区域.长话短说,最初的实现原型的截图如下:

  8. DICOM开源库

    转载于 http://blog.csdn.net/jackmacro/article/details/5850142 Developers used to search for libraries , ...

  9. 【刷机】Google Nexus s 蓝牙点击异常,无法启动,刷机解决方案

    1  问题详述 手头上有一部Google Nexus S ,本机自带的输入法不好用,想下载其他的输入法,想用蓝牙传输一下apk文件,点了一下蓝牙开关想要打开蓝牙功能,但奇怪的情况出现了,手机一直重启, ...

  10. 初次接触pyqt

    基本了解了pyqt的原理,到http://www.riverbankcomputing.co.uk/news下载安装好qt后,桌面上会出现Qt Designer. 我们可以利用它进行界面的设计,然后保 ...