题目链接
解题思路
堆维护:80pts
一看到这题,应该大部分人都会惊呼:这不就是堆的裸题吗!
好的,使用priority_queue
维护就好了。至于蚯蚓的增长,在全局打个Tag就差不多了。
ok上代码(很久以前写的,风格不太一样)
详细代码
#include<cstdio>
#include<queue>
#include<cmath>
using namespace std;
int n,m,q,u,v,t;
priority_queue<int> qee;
int delta;
double p;
int main()
{
scanf("%d%d%d%d%d%d",&n,&m,&q,&u,&v,&t);
p=double(u)/v;
for(int i=1;i<=n;i++)
{
int tmp;
scanf("%d",&tmp);
qee.push(tmp);
}
for(int i=1;i<=m;i++)
{
int l=qee.top()+delta;qee.pop();
int l1=floor(l*p);int l2=l-l1;
l1-=delta;l2-=delta;
l1-=q;l2-=q;
qee.push(l1);qee.push(l2);
delta+=q;
if(i%t==0) printf("%d ",l);
}
putchar('\n');
for(int i=1;!qee.empty();i++)
{
if(i%t==0) printf("%d ",qee.top()+delta);
qee.pop();
}
putchar('\n');
return 0;
}
时间复杂度 O ( m l o g 2 n ) O(mlog_2n) O(mlog2n).应该能过80pts.不知是不是洛谷的评测机不错,跑出了个85pts
发现隐藏的结论:100pts
emmm,我们要有一双发现秘密的眼睛
我们应该注意到,如果一只蚯蚓
α
\alpha
α比蚯蚓
β
\beta
β先被切(
l
e
n
g
t
h
α
≥
l
e
n
g
t
h
β
length_\alpha\geq length_\beta
lengthα≥lengthβ),那么把它们都剖开后,
α
\alpha
α的前端长度会大于
β
\beta
β的前端,后端同理。
这里稍加证明:
设两只蚯蚓
α
\alpha
α、
β
\beta
β的长度为
a
a
a和
b
b
b
(
a
≥
b
)
(a\geq b)
(a≥b),在
α
\alpha
α被切
t
t
t秒后,
β
\beta
β被切成了两段。
则我们可以得到,
a
a
a切得的新的两段的长度在过了
t
t
t秒后
a
1
=
⌊
a
∗
p
⌋
+
t
q
a_1=\lfloor a*p\rfloor+tq
a1=⌊a∗p⌋+tq
a
2
=
a
−
⌊
a
∗
p
⌋
+
t
q
a_2=a-\lfloor a*p\rfloor+tq
a2=a−⌊a∗p⌋+tq
b
b
b的新的两段为
b
1
=
⌊
p
(
b
+
t
q
)
⌋
b_1=\lfloor p(b + tq)\rfloor
b1=⌊p(b+tq)⌋
b
2
=
b
+
t
q
−
⌊
p
(
b
+
t
q
)
⌋
b_2=b+tq-\lfloor p(b + tq)\rfloor
b2=b+tq−⌊p(b+tq)⌋
我们采用做差法来比较
a
1
a_1
a1和
b
1
b_1
b1
我们先忽略取整
a
1
−
b
1
=
a
p
+
t
q
−
b
p
−
t
p
q
a_1-b_1=ap+tq-bp-tpq
a1−b1=ap+tq−bp−tpq
=
(
a
−
b
)
p
+
(
1
−
p
)
q
t
=(a-b)p+(1-p)qt
=(a−b)p+(1−p)qt
又
a
≥
b
,
0
<
p
<
1
a\geq b,0<p<1
a≥b,0<p<1
故
a
1
≥
b
1
a_1\geq b_1
a1≥b1
根据取整函数的性质:我们可以得到,当加上取整号时,仍有
a
1
≥
b
1
a_1\geq b_1
a1≥b1
同理有
a
2
≥
b
2
a_2\geq b_2
a2≥b2
所以,我们没必要用堆存储蚯蚓。我们只要根据时间,把切开的两条蚯蚓放进两个队列里,显然根据结论,这个队列里的元素会是不严格单调递减的。我们每次只要从三个队列头(还有一个队列存一次都没切的蚯蚓)找到长度最大的切开即可。其他细节与上面代码类似。
详细代码
#define USEFASTERREAD 1
#define rg register
#define inl inline
#define DEBUG printf("[Passing [%s] in line %d.]\n", __func__, __LINE__)
#define putline putchar('\n')
#define putsp putchar(' ')
#define Rep(a, s, t) for(rg int a = s; a <= t; a++)
#define Repdown(a, t, s) for(rg int a = t; a >= s; a--)
typedef long long ll;
#include<cstdio>
#define rs freopen("test.in", "r", stdin), freopen("test.out", "w", stdout)
#if USEFASTERREAD
char In[1 << 20], *ss = In, *tt = In;
#define getchar() (ss == tt && (tt = (ss = In) + fread(In, 1, 1 << 20, stdin), ss == tt) ? EOF : *ss++)
#endif
struct IO
{
void RS() {rs;}
template<typename T> inline IO r(T& x)const
{
x = 0; T f = 1; char ch = getchar();
for(; ch < '0' || ch > '9'; ch = getchar()) if(ch == '-') f = -1;
for(; ch >= '0' && ch <= '9'; ch = getchar()) x = x * 10 + int(ch - '0');
x *= f; return *this;
}
template<typename T> inline IO w(T x)const
{
if(x < 0) {putchar('-'); x = -x;}
if(x >= 10) w(x / 10);
putchar(x % 10 + '0'); return *this;
}
template<typename T> inline IO wl(const T& x)const {w(x), putline; return *this;}
template<typename T> inline IO ws(const T& x)const {w(x), putsp; return *this;}
inline IO l() {putline; return *this;}
inline IO s() {putline; return *this;}
}io;
template<typename T> inline T Max(const T& x, const T& y) {return y < x ? x : y;}
template<typename T> inline T Min(const T& x, const T& y) {return y < x ? y : x;}
template<typename T> inline void Swap(T& x, T& y) {T tmp = x; x = y; y = tmp;}
#include<queue>
#include<algorithm>
using namespace std;
const int MAXN = 100005;
const int MAXM = 7000005;
const int INF = 0x3f3f3f3f;
ll n, m, q, u, v, t;
queue<ll> Q[3];
priority_queue<int> pq;
ll a[MAXN + MAXM];
bool cmp(int a, int b) {return a > b;}
ll sum;
int main()
{
//io.RS();
io.r(n).r(m).r(q).r(u).r(v).r(t);
for(rg int i = 1; i <= n; i++) io.r(a[i]);
sort(a + 1, a + 1 + n, cmp);
for(rg int i = 1; i <= n; i++) Q[0].push(a[i]);
for(rg int i = 1; i <= m; i++)
{
ll mx = -INF, mxi = 0;
for(rg int j = 0; j < 3; j++)
if(!Q[j].empty() && Q[j].front() > mx) mx = Q[j].front(), mxi = j;
ll k = Q[mxi].front(); Q[mxi].pop();
k += sum;
int new1 = int(k * u / v), new2 = k - new1;
sum += q;
new1 -= sum; new2 -= sum;
Q[1].push(new1); Q[2].push(new2);
if(i % t == 0) io.ws(k);
}
io.l();
for(rg int i = 0; i < 3; i++)
while(!Q[i].empty()) pq.push(Q[i].front()), Q[i].pop();
for(rg int i = 1; !pq.empty(); i++)
{
if(i % t == 0) io.ws(pq.top() + sum);
pq.pop();
}
return 0;
}