您的位置:首页 > 其它

3463: [COCI2012] Inspector 分块+凸壳

2016-05-21 23:27 176 查看
可以发现答案一定在下凸壳上,我们考虑分块,然后如果有修改操作在块上打标记,查询的时候暴力重构。

由于T是单调的,所以维护一个队列,弹出队头元素直到到了T所在的直线就好了。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;

const int N=100005;
const long long INF=1ll<<60;

int n,m,b
,q
,st
,en
,belong
,L
,R
;
bool modify
;
long long ans;

struct line
{
int k;
long long b;
line() {};
line(int _,long long __) {k=_; b=__;};
}a
;

inline int read()
{
int a=0,f=1; char c=getchar();
while (c<'0'||c>'9') {if (c=='-') f=-1; c=getchar();}
while (c>='0'&&c<='9') {a=a*10+c-'0'; c=getchar();}
return a*f;
}

inline double pos(int x,int y)
{
return (double)(a[x].b-a[y].b)/(double)(a[y].k-a[x].k);
}

inline bool cmp(int x,int y)
{
return a[x].k==a[y].k?a[x].b>a[y].b:a[x].k<a[y].k;
}

inline void build(int x)
{
//  cout << "!!!! : " << x << endl;
int cnt=0,t=st[x];
q[++cnt]=t;
for (int i=t+1;i<=en[x];i++)
if (a[i].b!=-INF) q[++cnt]=i;
sort(q+1,q+cnt+1,cmp);
b[t]=q[1];
for (int i=2;i<=cnt;i++)
if (a[q[i]].k!=a[q[i-1]].k)
{
while (t>st[x]&&pos(b[t],b[t-1])>pos(q[i],b[t])) t--;
b[++t]=q[i];
}
L[x]=st[x]; R[x]=t;
}

inline void ask(int x,int T)
{
while (L[x]<R[x]&&(double)T>pos(b[L[x]],b[L[x]+1])) L[x]++;
if (L[x]<=R[x]) ans=max(ans,(long long)a[b[L[x]]].k*T+a[b[L[x]]].b);
}

inline void getans(int x,int y,int T)
{
int p=belong[x],q=belong[y];
if (p==q)
{
for (int i=x;i<=y;i++)
ans=max(ans,(long long)a[i].k*T+a[i].b);
return;
}
for (int i=x;i<=en[p];i++) ans=max(ans,(long long)a[i].k*T+a[i].b);
for (int i=st[q];i<=y;i++) ans=max(ans,(long long)a[i].k*T+a[i].b);
for (int i=p+1;i<q;i++)
{
if (modify[i]) build(i),modify[i]=false;
ask(i,T);
}
}

int main()
{
n=read(); m=read();
int block=sqrt(n);
int cnt=n/block+(n%block!=0);
for (int i=1;i<=n;i++)
belong[i]=(i-1)/block+1;
for (int i=1;i<=cnt;i++)
st[i]=(i-1)*block+1,en[i]=min(i*block,n);
for (int i=1;i<=n;i++) a[i]=line(0,-INF);
for (int i=1;i<=cnt;i++) L[i]=1;
for (int i=1;i<=m;i++)
{
int opt=read(),T=read(),x=read(),y=read();
if (opt==1)
{
int z=read();
a[x]=line(y,-(long long)y*T+z);
modify[belong[x]]=true;
}
else
{
if (x>y) swap(x,y);
ans=-INF;
getans(x,y,T);
ans!=-INF?printf("%lld\n",ans):puts("nema");
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: