您的位置:首页 > 其它

[luogu-2877]noip2016-day2-T2 蚯蚓 题解

2017-09-14 20:39 429 查看
题目传送门

题意解析:题目给了你n条蚯蚓,然后让你每次找出一条长度最长蚯蚓,然后把它切断,而且每次切断的位置都会告诉你(每次切开都是按照一个比例来的)。然后蚯蚓就会向你所知道的一样变成两节(为什么是瞬间恢复的?而且长度为0也是一种特殊的存在,居然还不死)。最后这次砍断结束后,除了这次被砍断的蚯蚓,都会长长q的长度(长得真快)。

My opinion:虽然这题有很多的槽点,但是我们还是得去做是不是,因为每次蚯蚓都会变长,所以我们是不可能直接出答案的。然后我就想到了,既然是每次找出最大值,那么是不是可以用堆,然而n有七百万,所以堆明显要被卡常(更别说我这种还把堆写错,强行从log变成n^2的人了)。所以只能使用O(n)处理这个问题,这样的话,我们只有一个办法了那就是单调队列,我们每次维护一个初始队列,把切开的两个分别在放在两个队列里。

总结:

1、输入。

2、单调队列维护。

3、输出。

神奇的代码:

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#define rep(i,a,n) for (int i=a;i<=n;i++)
#define per(i,a,n) for (int i=a;i>=n;i--)
#define Clear(a,x) memset(a,x,sizeof(a))
#define ll long long
#define INF 2000000000
#define eps 1e-8
#define db double
using namespace std;
ll read(){
ll x=0,f=1;
char ch=getchar();
while (ch<'0'||ch>'9') f=ch=='-'?-1:f,ch=getchar();
while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
return x*f;
}
const int maxn=100005,maxm=7000005;
int n,m,q,u,v,t;
int x[maxn],y[maxm],z[maxm];
int tx,ty,tz,wy,wz,mark;
bool cmp(int a,int b){
return a>b;
}
int work(int i,int s){
int k=0,tmp=-INF;
if (tx<n&&x[tx+1]+mark>tmp){
tmp=x[tx+1]+mark;
k=1;
}
if (ty<wy&&y[ty+1]+mark>tmp){
tmp=y[ty+1]+mark;
k=2;
}
if (tz<wz&&z[tz+1]+mark>tmp){
tmp=z[tz+1]+mark;
k=3;
}
if (i%t==0&&(i/t!=s/t)) printf("%d ",tmp);
else if (i%t==0) printf("%d",tmp);
if (k==1) tx++;
if (k==2) ty++;
if (k==3) tz++;
return tmp;
}
int main(){
n=read(),m=read(),q=read(),u=read(),v=read(),t=read();
rep(i,1,n) x[i]=read();
sort(x+1,x+n+1,cmp);
rep(i,1,m){
int tmp=work(i,m);
int X=floor((db)tmp*u/v);
int Y=tmp-X;
mark+=q;
y[++wy]=X-mark;
z[++wz]=Y-mark;
}
puts("");
rep(i,1,n+m)
work(i,n+m);
puts("");
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: