您的位置:首页 > 其它

Codeforce 222 div1

2014-01-31 13:42 309 查看
A

假设只有一个连通块,任选一个点入队,按bfs/dfs序删除即可.

trick: 要考虑有多个连通块的情况,不一定无解.

#define rep(i,n) for(int i=0 ; i<(n) ; i++ )
#define ls ((rt)<<1)
#define rs (((rt)<<1)+1)
#define mid ((l+r)>>1)
#define maxn 2000200
#define INF 100000000000000000
llong s;
struct node{
llong c,v;
};node build[maxn];
struct line{
llong v,d,t,X,Y;
llong f(llong x) {
if( (x-t)>=(INF+d)/v+1 ) return INF;
else return (x-t)*v+d;
}
llong x(llong y) {
return (y-d+v-1)/v+t;
}
};line seg[maxn];

node use[maxn];
int n,tot,front,tail;

bool cmp(node x,node y) {
return x.v<y.v;
}

void input() {
scanf("%d%I64d",&n,&s);
build[0] = (node){0,1};
rep (i,n) {
scanf("%I64d%I64d",&build[i+1].v,&build[i+1].c);
}
build[n+1] = (node){s,INF};
}

void pretreat() {
sort(build,build+n+2,cmp);
rep (i,n+2) {
if (i-1>=0 && build[i].v==build[i-1].v) continue;
while (tot && use[tot-1].c>=build[i].c) tot--;
use[tot++] = build[i];
}
}

double findcross(line a,line b) {
double va,vb,ta,tb,da,db,x;
va = a.v;    vb = b.v;
ta = a.t;    tb = b.t;
da = a.d;    db = b.d;
x = (va*ta-vb*tb+db-da)/(va-vb);
return x;
}

llong solv() {
seg[tail++] = (line){1,0,0,0,0};
rep (i,tot) {
while (tail-front>1 && seg[front].x(use[i].c) >= seg[front+1].x(use[i].c)) front++;
llong t = seg[front].x(use[i].c);
if (i==tot-1) return t;
line tmp = (line){use[i].v,seg[front].f(t)-use[i].c,t};
while (tail-front>1) {
if (findcross(seg[tail-2],seg[tail-1])>findcross(seg[tail-1],tmp)) tail--;
else break;
}
seg[tail++] = tmp;
}
return INF;
}

int main(){
//    freopen("test.txt","r",stdin);
input();
pretreat();
llong ans = solv();
printf("%I64d\n",ans);
return 0;
}


View Code

  (未知的bug,E题代码wa 13了....)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: