1. 程式人生 > 實用技巧 >手把手教你實現3D地圖的定時高亮和點選事件

手把手教你實現3D地圖的定時高亮和點選事件

[NOIp2016]蚯蚓

Description

一共有n只蚯蚓,每隻蚯蚓有一個長度,並且蚯蚓會按每年q釐米的速度增長。

現在每年選擇一隻最長的蚯蚓,將其按p的比例切成兩半,被切的的蚯蚓這一年不能增長,問每年被切的蚯蚓的長度和m年後所有蚯蚓的長度

Solution

發現蚯蚓每年長度都會改變,很難處理

但實際上每年只有被切斷的蚯蚓不會增長,所以可以考慮維護一個增加值的tag,這樣就可以那一個堆來維護最大的蚯蚓

但是這樣並不能過這道題

我們考慮優化這個做法,容易發現這個做法的複雜度瓶頸在於用堆維護當前時間最大蚯蚓是哪個

考慮到每次拿出去切的蚯蚓不會改變其他沒被切的蚯蚓的大小關係

而且切的比例一定,於是新增的兩條蚯蚓長度一點是遞減的

於是拿三個佇列維護一波就行了

#include<bits/stdc++.h>

using namespace std;

#define LL long long

inline LL read()
{
    LL f = 1 , x = 0;
    char ch;
    do
    {
        ch = getchar();
        if(ch=='-') f=-1;
    } while(ch<'0'||ch>'9');
    do
    {
        x=(x<<3) + (x<<1) + ch - '
0'; ch = getchar(); }while(ch>='0'&&ch<='9'); return f*x; } const int MAXN = 100000 + 5; queue<LL>Q[4]; int n,m,q,u,v,t; LL a[MAXN]; double p; LL add; inline bool cmp(int a1,int a2) { return a1 > a2; } inline int check() { int res = 1; while(!Q[res].size()) res++;
for(int i=res+1;i<=3;i++) if(Q[i].size()&&Q[i].front() > Q[res].front()) res = i; return res; } int main() { n = read(),m = read(),q = read(),u = read(),v = read();t = read(); p = 1.0 * u / v; for(int i=1;i<=n;i++) a[i] = read(); sort(a+1,a+n+1,cmp); for(int i=1;i<=n;i++) Q[1].push(a[i]); for(int i=1;i<=m;i++) { int cur = check(); if(i % t == 0) printf("%lld ",Q[cur].front() + add); LL res = Q[cur].front();Q[cur].pop(); LL Cut = (res + add) * u / v; LL res1 = Cut - add - q,res2 = res - Cut - q; Q[2].push(res1);Q[3].push(res2); add += q; } printf("\n"); for(int i=1;i<=n+m;i++) { int cur = check(); if(i % t == 0) printf("%lld ",Q[cur].front() + add); Q[cur].pop(); } }