题面

传送门

思路

首先看看我们到底要干什么:有$1e6$次询问,遍历$i$,每次要求一个形如$b_i \ast a_j - a_i \ast b_j$的东西的最大值

考虑如果一个$j$的决策在当前的$i$上比$k$这个位置更优会得到什么:

$b_i \ast a_j - a_i \ast b_j > b_i \ast a_k - a_i \ast b_k$

$b_i \ast (a_j-a_k) > a_i \ast (b_j-b_k)$

$\frac{b_i}{a_i} > \frac{b_j-b_k}{a_j-a_k}$

考虑对于询问区间维护右边那个玩意儿的下凸包$lis$,显然第一个满足$\frac{b_{lis[j]}-b_{lis[j+1]}}{a_{lis[j]}-a_{lis[j+1]}} > \frac{b_i}{a_i}$的$j$就是最优解,因为维护了下凸包所以这个东西可以二分

我们开一棵线段树维护每个线段树节点区间上的下凸包,查询的时候就把目标区间拆分到线段树节点上,再做一次上面的操作

线段树维护凸包的总复杂度是$O(q\log n)$,查询因为区间拆分完了二分,复杂度还是$O(q\log n)$

Code

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cassert>
#define MOD 1000000007
#define ll long long
using namespace std;
inline ll read(){
ll re=0,flag=1;char ch=getchar();
while(!isdigit(ch)){
if(ch=='-') flag=-1;
ch=getchar();
}
while(isdigit(ch)) re=(re<<1)+(re<<3)+ch-'0',ch=getchar();
return re*flag;
}
int n;ll g[1000010];int a[1000010],b[1000010],c[1000010];
int mmp[30000010],len[4000010];
int *q[4000010],*cur=mmp;//动态内存池,实际上大概2.5e7就够了
void build(int l,int r,int num){
q[num]=cur;len[num]=0;
cur+=r-l+2;
if(l==r) return;
int mid=(l+r)>>1;
build(l,mid,num<<1);
build(mid+1,r,num<<1|1);
}
inline double get(int l,int r){return (double)(b[r]-b[l])/(double)(a[r]-a[l]);}
void change(int l,int r,int num,int pos){插入新元素,维护log个凸包
while(len[num]>=2&&get(q[num][len[num]-1],q[num][len[num]])>get(q[num][len[num]],pos)) q[num][len[num]--]=0;
q[num][++len[num]]=pos;
if(l==r) return;
int mid=(l+r)>>1;
if(mid>=pos) change(l,mid,num<<1,pos);
else change(mid+1,r,num<<1|1,pos);
}
inline ll f(int i,int j){
return 1ll*b[i]*a[j]-1ll*b[j]*a[i];
}
ll query(int l,int r,int ql,int qr,int num,double lim,int now){
if(l>=ql&&r<=qr){//找到目标拆分区间,二分查询
if(len[num]==1) return f(now,q[num][1]);//注意特判凸包只有一个点的情况
l=1;r=len[num]-1;int mid;
while(l<r){
mid=(l+r)>>1;
if(get(q[num][mid],q[num][mid+1])<lim) l=mid+1;
else r=mid;
}
if(l==len[num]-1&&get(q[num][l],q[num][l+1])<lim) l++;//注意特判找到的倒数第二个点没有最后一个点优的情况
return f(now,q[num][l]);
}
int mid=(l+r)>>1;ll re=-1e18;
if(mid>=ql) re=max(re,query(l,mid,ql,qr,num<<1,lim,now));
if(mid<qr) re=max(re,query(mid+1,r,ql,qr,num<<1|1,lim,now));
return re;
}
int main(){
n=read();int i;ll tmp;
for(i=1;i<=n;i++) a[i]=read();
for(i=1;i<=n;i++) b[i]=read();
for(i=1;i<=n;i++) c[i]=read();
build(1,n,1);
for(i=1;i<=n;i++){
a[i]^=g[i-1];
b[i]^=g[i-1];
c[i]^=g[i-1];
change(1,n,1,i);
g[i]=(g[i-1]+(tmp=query(1,n,1,i-c[i],1,(double)b[i]/(double)a[i],i))%MOD+MOD)%MOD;
}
cout<<g[n]<<'\n';
}

Contest Hunter 模拟赛09 A [线段树维护斜率]的更多相关文章

  1. Contest Hunter 模拟赛09 C [树形dp+差分]

    题面 传送门 思路 又双叒叕是一道差分题我没想出来......记录一下 首先这个"所有祖先都比自己小"等价于"父亲比自己小" 这题的基础dp方程很显然,$dp[ ...

  2. Subsequence Count 2017ccpc网络赛 1006 dp+线段树维护矩阵

    Problem Description Given a binary string S[1,...,N] (i.e. a sequence of 0's and 1's), and Q queries ...

  3. [CSP-S模拟测试]:椎(线段树维护区间最值和单调栈)

    题目描述 虽不能至,心向往之. $Treap=Tree+Heap$ 椎$=$树$+$堆 小$\pi$学习了计算机科学中的数据结构$Treap$. 小$\pi$知道$Treap$指的是一种树. 小$\p ...

  4. 【BZOJ 2957】楼房重建&&Codechef COT5 Count on a Treap&&【NOIP模拟赛】Weed 线段树的分治维护

    线段树是一种作用于静态区间上的数据结构,可以高效查询连续区间和单点,类似于一种静态的分治.他最迷人的地方在于“lazy标记”,对于lazy标记一般随我们从父区间进入子区间而下传,最终给到叶子节点,但还 ...

  5. 3.28 省选模拟赛 染色 LCT+线段树

    发现和SDOI2017树点涂色差不多 但是当时这道题模拟赛的时候不会写 赛后也没及时订正 所以这场模拟赛的这道题虽然秒想到了LCT和线段树但是最终还是只是打了暴力. 痛定思痛 还是要把这道题给补了. ...

  6. 4.11 省选模拟赛 序列 二分 线段树优化dp set优化dp 缩点

    容易想到二分. 看到第一个条件容易想到缩点. 第二个条件自然是分段 然后让总和最小 容易想到dp. 缩点为先:我是采用了取了一个前缀最小值数组 二分+并查集缩点 当然也是可以直接采用 其他的奇奇怪怪的 ...

  7. 【10.6校内测试】【小模拟】【hash+线段树维护覆盖序列】

    一开始看到题就果断跳到T2了!!没想到T2才是个大坑,浪费了两个小时QAQ!! 就是一道小模拟,它怎么说就怎么走就好了! 为什么要用这么多感叹号!!因为统计答案要边走边统计!!如果每个数据都扫一遍20 ...

  8. The 2019 Asia Nanchang First Round Online Programming Contest C(cf原题,线段树维护矩阵)

    题:https://nanti.jisuanke.com/t/41350 分析:先将字符串转置过来 状态转移,因为只有5个状态,所以 i 状态到 j 状态的最小代价就枚举[i][k]->[k][ ...

  9. 7.18 NOI模拟赛 因懒无名 线段树分治 线段树维护直径

    LINK:因懒无名 20分显然有\(n\cdot q\)的暴力. 还有20分 每次只询问一种颜色的直径不过带修改. 容易想到利用线段树维护直径就可以解决了. 当然也可以进行线段树分治 每种颜色存一下直 ...

随机推荐

  1. Java小功能大杂烩

    生成UUID: import java.util.UUID; public class ProductUUID { // 随机返回前十位的UUID public static String getUU ...

  2. laravel 中出现SQLSTATE[HY000] [2002] 如何解决?

    在日常开发中总是难免遇到各式各样的错误,还有许多错误常常是重复出现的 以下是报错信息! SQLSTATE[HY000] [2002] ������ӷ���һ��ʱ���û���ȷ�

  3. Windows使用Node.js自动生成Vue.js模版环境部署步骤-----记录

    node.js官网下载并安装node 进入node文档目录下,运行cmd 输入 node -v 查看node版本 出现表示安装完成 输入 npm -v 显示npm版本信息 安装cnpm 输入 npm ...

  4. maven中settings文件的配置

    鉴于上一个博客写的maven打包,读者老爷们可能找不到settings文件的配置,这里专门附上settings文件的配置: 有的settings文件只含有一些空标签,需要手动去配置. <?xml ...

  5. P1189 SEARCH(逃跑的拉尔夫)

    P1189 SEARCH 题目描述 年轻的拉尔夫开玩笑地从一个小镇上偷走了一辆车,但他没想到的是那辆车属于警察局,并且车上装有用于发射车子移动路线的装置. 那个装置太旧了,以至于只能发射关于那辆车的移 ...

  6. Entity Framework + WCF 远程调用出错

            在使用Entity Framework中使用WCF,在程序中调用服务一直报错,我一直以为是WCF的哪个地方的配置有问题,找来找去,一直没有解决.         最后在网上找到一篇文章 ...

  7. Spring 整合 Shiro

    一.引入依赖 <!-- spring start --> <dependency> <groupId>org.springframework</groupId ...

  8. Linux-OpenSUSE折腾-1(Qt安装,Chrome安装)

    先上图,大蜥蜴还是不错的,偶然看到了大蜥蜴这个系统,我就觉得又可以折腾几天了,先上图 OpenSUSE有一个入门介绍的网站写的相当不错,感兴趣的可以连接过去:https://lug.ustc.edu. ...

  9. 自动化测试元素查找利器firepath介绍

    自动化测试查找元素和确定元素xpath路径是否正确在业界有个很好的工具就是firefox 浏览器的 firepath 问题: firefox 最新版本已经不支持firebug和firepath这两个插 ...

  10. Bitcoin-NG

    Bitcoin-NG,一个新的可扩展的区块链协议 Bitcoin-NG仅受限于网络的传输延时,它的带宽仅受限于个人节点的处理能力.通过将比特币的区块链操作分解为两部分来实现这个性能改善:首领选择(le ...