1. 程式人生 > >洛谷P2827 蚯蚓(隱藏的單調的佇列)

洛谷P2827 蚯蚓(隱藏的單調的佇列)

題解
(不行,我先吐槽一下,因為少了兩個等號我調了一個晚上!!!可惡啊(〃>皿<),35分到100分的差距!)

首先,我們可以先模擬一下切蚯蚓的過程,會發現,後切成蚯蚓肯定要比先切成蚯蚓短。假設現在有蚯蚓a,ba,b並且La>LbL_a>L_b,對於第ii次切割,切割蚯蚓aa,長度為LaL_a,將其切割為x=pLax=p\cdot L_ay=Laxy = L_a-x,對於第j(i<jm)j(i<j\leq m)次切割,切割蚯蚓bb,將其切割為x1=

pLbx_1=p\cdot L_by1=Lbx1y_1 = L_b-x_1,此時之前第ii次切割的兩條蚯蚓的長度應該為x+(ji)x+(j-i)y+(ji)y+(j-i),因此有
{pLa+(ji)>pLb+(ji)La(1p)+(ji)>Lb(1p)+(ji)\begin{cases} p\cdot L_a+(j-i)>p\cdot L_b+(j-i)\\\\ L_a\cdot (1-p)+(j-i)>L_b\cdot(1-p)+(j-i)\end{cases}

因此我們可以利用這個規律,將蚯蚓分為三部分:

1.從大到小排好序的未切割的蚯蚓
2.每次切割完蚯蚓長度相對短的蚯蚓
3.每次切割完蚯蚓長度相對長的蚯蚓
然後每次切割的時候在這三隊裡面選擇最長的蚯蚓切割即可。

還有一點就是對於每次切割時未被切割的蚯蚓會增加長度qq,因為每次增加的時候是固定的qq,因此我們可以利用差分思想,標記增量,每次入隊的時候減去,查詢的時候再加上。

#include<bits/stdc++.h>

using namespace std;
const int N = 7000010; int n,m,q,u,v,t,a[N],b[N],c[N]; int main() { #ifndef ONLINE_JUDGE freopen("input.in", "r", stdin); #endif vector<int> ans; cin >> n >> m >> q >> u >> v >> t; for (int i = 0; i < n; ++i) cin >> a[i]; int front1 = 0, rear1 = n, front2 = 0, rear2 = 0, front3 = 0, rear3 = 0; sort(a, a + n, greater<int>()); int tmp, sum = 0; double p = 1.0 * u / v; for (int i = 1; i <= m; ++i) { if (front1 < rear1) { if (a[front1] >= max(b[front2], c[front3])) { tmp = a[front1++]; } else if (b[front2] >= max(a[front1], c[front3])) { tmp = b[front2++]; } else { tmp = c[front3++]; } } else { if (b[front2] > c[front3]) tmp = b[front2++]; else tmp = c[front3++]; } tmp += sum; //加上標記 sum += q; //更新標記 int x = floor(p * tmp), y = tmp - x; x -= sum, y -= sum; b[rear2++] = x, c[rear3++] = y; if (i % t == 0) cout << tmp << ' '; } puts(""); for (int i = front1; i < rear1; ++i) ans.push_back(a[i]); for (int i = front2; i < rear2; ++i) ans.push_back(b[i]); for (int i = front3; i < rear3; ++i) ans.push_back(c[i]); sort(ans.begin(), ans.end(), greater<int>()); for (int i = 0; i < ans.size(); ++i) { if ((i + 1) % t == 0) cout << ans[i] + sum << ' '; } return 0; }

相關推薦

P2827 蚯蚓(隱藏單調佇列)

題解 (不行,我先吐槽一下,因為少了兩個等號我調了一個晚上!!!可惡啊(〃>皿<),35分到100分的差距!) 首先,我們可以先模擬一下切蚯蚓的過程,會發現,後切成蚯蚓肯定要比先切成蚯蚓短。假設現在有蚯蚓a,ba,ba,b並且La&gt;LbL_a&a

P2827 蚯蚓(NOIp2016提高組D2T2)

mat 希望 c++ ffffff define fff 空行 特殊 到來 題目描述 本題中,我們將用符號?c?表示對c向下取整,例如:?3.0?=?3.1?=?3.9?=3。 蛐蛐國最近蚯蚓成災了!隔壁跳蚤國的跳蚤也拿蚯蚓們沒辦法,蛐蛐國王只好去請神刀手來幫他們消滅蚯蚓。

P2827 蚯蚓 【優先隊列】

個數 badge 空格 之間 new lan fine floor 結果 洛谷 P2827 蚯蚓 題目描述(題目還是到鏈接裏去看吧(點標題),這裏復制的時候有點問題) 本題中,我們將用符號 \lfloor c \rfloor?c? 表示對 cc 向下取整,例如: \lflo

P2827 蚯蚓 解題報告

洪荒之力 strong pri 符號 理解 .com image ++ can P2827 蚯蚓 題目描述 本題中,我們將用符號 \(\lfloor c \rfloor\) 表示對 \(c\) 向下取整,例如:\(\lfloor 3.0 \rfloor = \lfloor

[USACO18JAN]Lifeguards P 黑題,單調佇列優化DP

傳送門:戳我 這道題有兩個版本,S和P,S是K等於1的情況,顯然可以用線段樹水過。 P版本就難了很多,洛谷黑題(NOI/NOI+/CTSC),嘿嘿。 我自己也不是很理解,照著題解寫了一遍,然後悟到了一點東西。 dp方程很好想: dp[i][j]表示處理到第i個元素,已經刪掉了j個,但取了第i個。

P1091 合唱隊形題解(,動態規劃LIS,單調佇列)

先上題目 P1091 合唱隊形(點選開啟題目) 題目解讀: 1.由T1​<...<Ti​和Ti​>Ti+1​>…>TK​可以看出這題涉及最長上升子序列和最長下降子序列 2.注意點:當n=1時是允許的,就是說沒有因為i=1,Ti=T1,所以最後全部人都要出列這種說法 &n

【題解】P1886 滑動視窗(單調佇列)

(之前從未聽說過這道題目 來到qbxt後大佬們都早就切掉此題了 倍感慚愧qwq) 題目大意就是給定一個序列A與要求的長度k,讓我們輸出A中所有長度為k的區間的最大值和最小值。 看到資料範圍後我們發現暴力會炸掉,所以要考慮比較簡潔的方法。這裡我們維護一個元素單調遞減的佇列求

P2827 蚯蚓

題目描述 本題中,我們將用符號[c]表示對c向下取整,例如:[3.0」= [3.1」=[3.9」=3。 蛐蛐國最近蚯蚓成災了!隔壁跳蚤國的跳蚤也拿蚯蚓們沒辦法,蛐蛐國王只好去請神刀手來幫他們消滅蚯蚓。 蛐蛐國裡現在共有n只蚯蚓(n為正整數)。每隻蚯蚓擁有長度,我們設

【noip2016】【P2827蚯蚓

初始 開始 code space cout iostream lag == std 這個題只知道可以用優先隊列去做,但是不知道正解想法,看到題解後恍然大悟,詳情請看代碼中間 #include<algorithm> #include<iostream

P4147 玉蟾宮 單調棧/懸線法

正解:單調棧/懸線法 解題報告: ummm這題我當初做的時候一點思路也沒有隻會暴力出奇跡:D(啊聽說暴力好像能水過去呢,,, 然後當初是看的題解,然後學了下懸線法 然後就忘了:D 然後我現在看發現看不懂遼:D #論寫題解的好處:D 所以趕緊來寫個題解QAQ ummm懸線法這個玩意兒會單獨寫個學

1950 長方形 (單調棧)

懶得放題目連結了 qwq (果然我是菜的真實,單調棧都不會,gg) 首先我們看到這個題。 應該會想到就是直接列舉行,然後計算當前行的答案。 那現在,對於每一行來說,如果我們能夠維護出\(h[j]\)表示第\(j\)列的最近的一個不合法的位置。 那麼實際上就是求一堆矩形的並的一個圖形中。 有多少個矩形。

p3378 堆--基於優先佇列實現

加入了讀入掛,如果去掉greater<int>,則為最大堆 #include<cstdio> #include<queue> //不要忘記標頭檔案 using namespace std; priority_queue<int,vector<in

3594 [POI2015]WIL-Wilcze doły(單調佇列

題目 給定一個長度為n的序列,你有一次機會選中一段連續的長度不超過d的區間,將裡面所有數字全部修改為0。請找到最長的一段連續區間,使得該區間內所有數字之和不超過p。 特性 選擇一個區間[i,i+d-1],那麼我們選擇的最長區間一定在這個區間附近,也就是連續的。 題解 單調佇列

2018.09.26P3957 跳房子(二分+單調佇列優化dp)

傳送門 表示去年考普及組的時候失了智,現在看來並不是很難啊。 直接二分答案然後單調佇列優化dp檢驗就行了。 注意入隊和出隊的條件。 程式碼: #include<bits/stdc++.h>

P1419 尋找段落(二分+單調佇列)

題解:題中需要我們去求一個最大的長度在[S,T][S,T][S,T]之間的連續子序列平均值。 即x=∑i=LRaiR−L+1(S≤R−L+1≤T)x = \frac{\sum_{i=L}^R a_i}{R-L+1} (S\leq R-L+1\leq T) x=

【題解】P4853[非酋yyf的sif之旅]B.yyf hates choukapai 單調佇列優化DP

題目連結 賽後題解 #include<cstdio> const int M=8e4+5,C=3e3+5,N=45,S=N*C+M; int a[S],b[S],n,m,c,d,sum,hd[N],tl[N],s,q[N][S][2],f[S]

P3594 [POI2015]WIL-Wilcze doły【單調佇列

時空限制 1000ms / 128MB 題目描述 給定一個長度為n的序列,你有一次機會選中一段連續的長度不超過d的區間,將裡面所有數字全部修改為0。請找到最長的一段連續區間,使得該區間內所有數字之和不超

[P2422]良好的感覺[單調佇列]

開始寫了個隊頭隊尾都pop的假做法...還搞到了70pts 後來拍了拍發現自己傻了 int n, a[MAXN], l[MAXN], r[MAXN], sta[MAXN], top;//l[i], r[i]是a[i]作為最小值的最左和最右端點 ll pre[MAXN]; int main() { ll

P1419】 尋找段落(二分答案,單調佇列

題目連結 開始還以為是尺取。發現行不通。 一看標籤二分答案,恍然大悟。 二分一個\(mid\)(實數),把數列裡每個數減去\(mid\),然後求字首和,在用單調佇列維護\(sum[i-t\text{~}i-s]\)的最小值,用\(sum[i]\)減去它,如果大於等於\(0\)就說明\(mid\)可行。 #