比赛的时候因为卡内存,在抠内存的时候改错了,导致赛内没有AC,赛后发现数组开的很小都可以AC。

分析题意我们发现,这题需要求出所有存在的直线形成的上凸壳,那么查询$[L,R]$时在凸壳上二分导数,找到最大值即可。

因为有删除操作,故离线求出每条直线存在的时间区间,在时间线段树上打标记,那么这样会转化成$O(n\log n)$次插入。

那么现在需要维护一个数据结构,支持插入直线,询问单点最值,这显然可以使用李超线段树。

沿着时间线段树进行dfs,用一个栈按时间记录所有修改,那么可以很方便地实现李超线段树的还原。

时间复杂度$O(n\log^2n)$。

#include<cstdio>
#include<algorithm>
#include<stack>
#include<map>
using namespace std;
typedef pair<int,int>P;
typedef long long ll;
const int N=100010,M=1500000,E=200010;
const int eps=5;
const int inf=1000000000;
const ll offset=2000000000LL;
const ll infll=1LL<<62;
int Case,n,m,i,op,x,y;
int st[N],en[N],cur;
int cq,que[N][2],g[N],nxt[N];
ll ans[N];
int G[131111],V[M],NXT[M],ED;
map<P,stack<int> >idx; int root,tot,l[E],r[E],val[E]; int pool[E][2],cpool; struct LINE{
int k,b;
}a[N]; inline ll cal(int x,int p){return 1LL*a[x].k*p+a[x].b;} inline void addedge(int x,int y){
nxt[y]=g[x];g[x]=y;
}
void build(int x,int a,int b){
G[x]=0;
if(a==b)return;
int mid=(a+b)>>1;
build(x<<1,a,mid);
build(x<<1|1,mid+1,b);
}
void tag(int x,int a,int b,int c,int d,int p){
if(c<=a&&b<=d){
V[++ED]=p;
NXT[ED]=G[x];
G[x]=ED;
return;
}
int mid=(a+b)>>1;
if(c<=mid)tag(x<<1,a,mid,c,d,p);
if(d>mid)tag(x<<1|1,mid+1,b,c,d,p);
}
void ins(int&x,int a,int b,int p,int f){
if(!val[x]){
x=++tot;
l[x]=r[x]=0;
pool[++cpool][0]=x;
pool[cpool][1]=-f;
val[x]=p;
return;
}
if(cal(p,a)<cal(val[x],a)&&cal(p,b)<cal(val[x],b)){
pool[++cpool][0]=x;
pool[cpool][1]=val[x];
val[x]=p;
return;
}
if(cal(p,a)>=cal(val[x],a)&&cal(p,b)>=cal(val[x],b)){
return;
}
if(a==b)return;
ll mid=((offset+a+b)>>1)-inf;
ins(l[x],a,mid,p,x);
ins(r[x],mid+1,b,p,x);
}
inline void umin(ll&a,ll b){if(a>b)a=b;}
inline void umax(ll&a,ll b){if(a<b)a=b;}
ll TMP;
void ask(int x,int a,int b,int c){
if(!val[x])return;
umin(TMP,cal(val[x],c));
if(a==b)return;
ll mid=((offset+a+b)>>1)-inf;
if(c<=mid)ask(l[x],a,mid,c);else ask(r[x],mid+1,b,c);
}
inline void retrace(int pos){
while(cpool>pos){
int x=pool[cpool][0],y=pool[cpool--][1];
val[x]=y;
if(y<=0){
tot--;
if(y<0){
if(l[-y]==x)l[-y]=0;
if(r[-y]==x)r[-y]=0;
}
}
}
}
inline ll query(int L,int R){
//find max t that f(t)>f(t-1)
int o=L++;
while(L<=R){
ll mid=((offset+L+R)>>1)-inf;
TMP=infll;
ask(root,-inf,inf,mid);
ll u=TMP;
TMP=infll;
ask(root,-inf,inf,mid-1);
if(u>TMP)L=(o=mid)+1;else R=mid-1;
}
TMP=infll;
ask(root,-inf,inf,o);
return TMP;
}
void dfs(int x,int a,int b){
int pos=cpool;
for(int i=G[x];i;i=NXT[i]){
ins(root,-inf,inf,V[i],0);
}
if(a==b){
for(int i=g[a];i;i=nxt[i]){
ans[i]=query(que[i][0],que[i][1]);
}
retrace(pos);
return;
}
int mid=(a+b)>>1;
dfs(x<<1,a,mid);
dfs(x<<1|1,mid+1,b);
retrace(pos);
}
int main(){
scanf("%d",&Case);
while(Case--){
scanf("%d%d",&n,&m);
cur=1;
for(i=1;i<=n;i++){
scanf("%d%d",&a[i].k,&a[i].b);
idx[P(a[i].k,a[i].b)].push(i);
st[i]=1;
}
for(i=1;i<=m;i++){
scanf("%d%d%d",&op,&x,&y);
if(op==0){
cq++;
que[cq][0]=x;
que[cq][1]=y;
addedge(cur,cq);
}
if(op==1){
cur++;
a[++n].k=x;
a[n].b=y;
st[n]=cur;
idx[P(x,y)].push(n);
}
if(op==2){
int z=idx[P(x,y)].top();
idx[P(x,y)].pop();
en[z]=cur++;
}
}
for(i=1;i<=n;i++)if(!en[i])en[i]=cur;
build(1,1,cur);
for(i=1;i<=n;i++)tag(1,1,cur,st[i],en[i],i);
dfs(1,1,cur);
for(i=1;i<=cq;i++)printf("%lld\n",ans[i]); cq=0;
for(i=1;i<=n;i++)en[i]=0;
for(i=1;i<=cur;i++)g[i]=0;
ED=0;
idx.clear();
}
}

  

ZOJ3967 : Card Game的更多相关文章

  1. Lesson 3 Please send me a card

    Text Postcards always spoil my holidays. Last summer, I went to Italy. I visited museums and sat in ...

  2. iOS - Card Identification 银行卡号识别

    1.CardIO 识别 框架 GitHub 下载地址 配置 1.把框架整个拉进自己的工程,然后在 TARGETS => Build Phases => Link Binary With L ...

  3. HDOJ 4336 Card Collector

    容斥原理+状压 Card Collector Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/O ...

  4. Opensuse enable sound and mic card

    Install application pavucontrol Run pavucontrol You will see the configuration about sound card and ...

  5. 进监狱全攻略之 Mifare1 Card 破解

    补充新闻:程序员黑餐馆系统 给自己饭卡里充钱 ,技术是双刃剑,小心,小心! 前言 从M1卡的验证漏洞被发现到现今,破解设备层出不穷,所以快速傻瓜式一键破解不是本文的重点,年轻司机将从本文中获得如下技能 ...

  6. Card(bestcoder #26 B)

    Card Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submi ...

  7. [OpenJudge 3061]Flip The Card

    [OpenJudge 3061]Flip The Card 试题描述 There are N× Ncards, which form an N× Nmatrix. The cards can be p ...

  8. [杂谈]交通工具orca card

    How and Where to Use the ORCA Card The Microsoft ORCA card provides unlimited rides on all buses, tr ...

  9. [OrangePi] Backup internal EMMC to SD Card

    Boot your Orange PI board from EMMC without SD Card inserted login insert your SD Card Run: sudo ins ...

随机推荐

  1. 饮冰三年-人工智能-linux-01通过VM虚拟机安装contes系统

    先决条件:VM虚拟机的安装.contes系统的镜像文件 1:创建新的虚拟机 2:下一步,稍后安装操作系统 3:选择对应的系统 4:选择对应的路径 至此虚拟机已经创建完成(相当于买了一台新电脑) 5:编 ...

  2. python requests的content和text方法的区别

    requests对象的get和post方法都会返回一个Response对象,这个对象里面存的是服务器返回的所有信息,包括响应头,响应状态码等.其中返回的网页部分会存在.content和.text两个对 ...

  3. Python初探list

    今天要说一个新概念--list,中文可以翻译成列表,是用来处理一组有序项目的数据结构.想象一下你的购物清单.待办工作.手机通讯录等等,它们都可以看作是一个列表.说它是新概念也不算确切,因为我们之前已经 ...

  4. Python深度学习案例1--电影评论分类(二分类问题)

    我觉得把课本上的案例先自己抄一遍,然后将书看一遍.最后再写一篇博客记录自己所学过程的感悟.虽然与课本有很多相似之处.但自己写一遍感悟会更深 电影评论分类(二分类问题) 本节使用的是IMDB数据集,使用 ...

  5. Dom,查找标签和操作标签

    Dom,查找标签和操作标签 文档对象模型(Document Object Model,DOM)是一种用于HTML和XML文档的编程接口.它给文档提供了一种结构化的表示方法,可以改变文档的内容和呈现方式 ...

  6. CMD批处理——forfiles命令使用,自动删除过期备份文件

    公司服务器用来备份数据的硬盘过段时间就会被备份文件占满,弄得我老是要登录到服务器去手工删除那些老的文件,有时忘记了就会导致硬盘空间不足而无法备份.因为只要保留最近几天的备份,如果可以做一个批处理让系统 ...

  7. SQLServer 常见高CPU利用率原因

    1.缺失索引: USE AdventureWorks2014 SET STATISTICS TIME ON; SET STATISTICS IO ON ; SELECT per.FirstName,p ...

  8. ubuntu ibus pinyin输入法异常

    http://blog.csdn.net/granvillegao/article/details/41115211 命令行运行 ibus-setup 在常规页面,取消了“在应用程序窗口中启用内嵌编辑 ...

  9. js与jquery常用数组方法总结

    昨天被问数组方法的时候,问到sort()方法是否会改变原来的数组.本来我猜是不会,也是这么说,马上我又觉得,知识这种东西,不确定的时候直接说不确定或不知道就好,只是凭借着不确定的猜测或者是记忆,害人害 ...

  10. C语言整理——文件系统和文件访问

    标准C中规定了文件系统的访问和对文件本身的访问.不管是windows系统或者是泛unix系统,都实现了这些接口.在了解这些知识后,跨平台编程也将非常容易. 对文件系统的访问接口有: chdrive() ...