1. 程式人生 > >2018寧夏邀請賽網賽 G.Trouble of Tyrant(單調棧)

2018寧夏邀請賽網賽 G.Trouble of Tyrant(單調棧)

題意:

有n個點,2n-3條邊的圖。點 1 到每個點有一條邊,編號相鄰的兩個點有一條邊。q次詢問,每次詢問一個增量d,問圖中每條邊都增加 d 後,1 到 n 的最短路是多少。增量獨立,不累加。
1 <= n,q <= 1e5

分析:

用 dp[i] 表示經過 i 條邊到達 n 的最短路長度,每條路是唯一的。如果每條邊增加了長度 d 後最短路發生了改變,那新的最短路一定是邊數更少了。所以問題轉化成了對於所有 dp[i] ,面對一個增量 k,dp[i] + k * i 最小值是多少。

若dp[i] < dp[j] && i > j, 假如增加增量後dp[i] + k * i >= dp[j] + k* j,即最短路換成了 j 條邊的,有 (dp[j] - dp[i]) / (j - i) >= -k。

維護一個邊數由少到多,距離由多到少的單調棧。使得相鄰兩點間的斜率慢慢變大(斜率都是負數,斜率絕對值是慢慢變小的)。

這裡寫圖片描述

考慮這樣一種情況,棧中原本有A和B,此時C要入棧,我們應該把B踢出棧。為什麼呢?一種簡單的思考方法是,假如ABC共線,那麼取到最小值的不是C就是AB,A和B是一樣的。那現在B高出來了一點點,而A沒變,B顯然就競爭不過A,B永遠取不到最小值。另一種考慮方法是,寫出AB,AC,BC的斜率,分類討論可以發現,無論增量 k 取何值,最小值都是A或C。

解決了這個問題,就可以維護一個這個樣子的棧。
這裡寫圖片描述

將增量由小到大排序,然後逐個查詢。因為 k 由小到大,所以-k由大到小,越靠後的 k 越有可能在棧中比較的越遠。

大佬寫的程式碼:

#include <bits/stdc++.h>

using namespace std;

struct Node{
    int x;
    long long y;
    Node(){}
    Node(int x,long long y):x(x),y(y){}
};
int cnt;

int last;

const int N = 1e5+10;
int a[N],aa[N];
long long sum[N],dp[N];
Node T[N];

struct Query{
    int id;
    int val;
    long
long ans; }; Query que[N]; bool cmp(Query a,Query b){ return a.val<b.val; } bool cmp2(Query a,Query b){ return a.id<b.id; } long long X(Node a, Node b, Node c){ return (b.x-a.x)*(c.y-a.y)-(c.x-a.x)*(b.y-a.y); } bool pd(Node a,Node b, long long c){ return (a.y-b.y)<=c*(b.x-a.x); } int main() { //freopen("1.txt","r",stdin); int Case; scanf("%d",&Case); while (Case--){ int n; scanf("%d",&n); int q; scanf("%d",&q); for (int i=2;i<=n;i++){ scanf("%d",&a[i]); } for (int i=2;i<=n-1;i++){ scanf("%d",&aa[i]); } aa[1] = a[2]; sum[n]=0; for (int i=n-1;i>=1;i--) sum[i]=sum[i+1]+aa[i]; cnt=0; for (int i=1;i<=n-1;i++){ dp[i] = a[n-i+1] + sum[n-i+1]; if (cnt && T[cnt-1].y<=dp[i]) continue; while (cnt>=2 && X(T[cnt-2],T[cnt-1],Node(i,dp[i]))<=0) cnt--; T[cnt++] = Node(i,dp[i]); } for (int i=1;i<=q;i++){ que[i].id = i; scanf("%d",&que[i].val); } sort(que+1,que+q+1,cmp); for (int i=1;i<=q;i++){ while (cnt>=2 && pd(T[cnt-2],T[cnt-1],que[i].val)) cnt--; int last = T[cnt-1].x; que[i].ans = dp[last]+que[i].val*last; } sort(que+1,que+q+1,cmp2); for (int i=1;i<=q;i++){ printf("%lld",que[i].ans); if (i==q) printf("\n");else printf(" "); } } return 0; }

相關推薦

2018寧夏邀請賽 G.Trouble of Tyrant單調

題意: 有n個點,2n-3條邊的圖。點 1 到每個點有一條邊,編號相鄰的兩個點有一條邊。q次詢問,每次詢問一個增量d,問圖中每條邊都增加 d 後,1 到 n 的最短路是多少。增量獨立,不累加。 1 <= n,q <= 1e5 分析: 用

2018牛客暑期ACM多校訓練營第一場F.Sum of Maximum(組合數學+拉格朗日插值)

題目連結:https://www.nowcoder.com/acm/contest/139#question 轉載出處:http://tokitsukaze.live/2018/07/19/2018niuke1.F/   程式碼: #include <bits/

2018 ACM-ICPC 寧夏邀請賽 A. Maximum Element In A Stack思路題

題意:讓維護一個棧,每次操作之後詢問棧裡的最大值xi,求(1*x1)^(2*x2)^……^(n*xn)的結果。 思路分析:首先暴力每次入棧找最大值肯定T,現場賽時我們隊想到的思路是維護一個stack和一個multiset(或者map),每次push最大值是m.end()

ACM-ICPC 2018 焦作賽區網路 H. String and Times字尾自動機

下午打的網路賽,一上來就開了這題,打算秒,結果發現題面沒有給字串長度,最後還是出題人在提問區補的,真的想打人。 字尾自動機裸題,大概就是以下這兩題合在一起: hihocoder上都有題解。 很裸,求一下endpos,再根據自動機性質,用maxl

2018 Multi-University Training Contest 3 hdu 6319 Problem A. Ascending Rating單調

題意 給定一個序列 a[1..n],對於每個長度為 m 的連續子區間,求出區間 a 的最大值以及從左往右掃描該區間時 a 的最大值的變化次數。   題解 滑動視窗,從左到右,維護一個單調棧,從小到大   程式碼 #include<stdio.h&

2018山東省ACM省G題-Game

mov rest CA -- eve sca 山東 for each represent Alice and Bob are playing a stone game. There are n piles of stones. In each turn, a player

2018 ICPC北京】 A Saving Tang Monk IIBFS

《Journey to the West》(also 《Monkey》) is one of the Four Great Classical Novels of Chinese literature. It was written by Wu Cheng’en during the Min

2018 icpc南京網路G(線段樹)

思路:因為只有1e5的資料。我們可以模擬一下所有情況全算出來,把答案存下來即可。但會一遍一遍的遍歷超時,我們可以優化遍歷的方式,因為只有1e5的房間,我們每次找的房間都是小於當前新燈泡數且最前面的房間。這個查詢用一顆線段樹既可以解決。 我們每次找到一個滿足的房間就讓當前燈泡

2018 ICPC 瀋陽網路 G. Spare Tire 1到n中與m互質的平方和與本身和

計蒜客 全部課程  學習計劃 題庫 比賽  Spare Tire 編輯程式碼  15.27%  1000ms  131072K A sequence of integer \lbrace a_n \rbrace{an​} can be expressed as

2018牛客暑期ACM多校訓練營第三場C Shuffle Cards可持久化平衡樹/splay

car 訓練營 shu cas queue math getchar() %d fir 題意 牌面初始是1到n,進行m次洗牌,每次抽取一段放到最前面。求最後的序列。 分析 神操作!!!比賽時很絕望,splay技能尚未點亮,不知道怎麽用。 殊不知,C++庫裏有rope

2018牛客暑期ACM多校訓練營第九場A -Circulant Matrix(FWT)

html ++ oid logs sync const stdout i++ scan 分析 大佬說看樣例就像和卷積有關。 把題目化簡成a*x=b,這是個xor的FWT。 FWT的講解請看:https://www.cnblogs.com/cjyyb/p/9065615

gym 101064 G.The Declaration of Independence 主席樹

直接 兩個 enc upd () class 我們 lar 元素 題目鏈接: 題意: n個操作,有兩種操作: E p c 在序號為p的隊列尾部插入c得到新的隊列,序號為i D p 查詢並刪除序號為p的隊列頂部的元素,得到序號為i的新隊列 思路: 需要

ACM-ICPC 2018 沈陽賽區絡預賽 Made In HeavenK短路題解

clas names turn scan sin cst ++ ini struct 思路:K短路裸題 代碼: #include<queue> #include<cstring> #include<set> #include<ma

2017瀋陽網路G XOR 分塊分類討論sqrt

題意:一棵樹,點權,Q次詢問,A---B路徑上每K個點的異或和 連結:點選開啟連結 思路:分類討論,k小於200,類似dp的預處理,在求lca的過程中可以求出來,k大於200,直接暴力跳,最多跳sqrtn步,其中還帶個log的倍增。1200ms AC。。 PS  :場上手殘

2018杯的pwn簽到題詳細過程

題目: 連結:https://pan.baidu.com/s/1WcO-y2MQ6Wb17PqL2dxyyA 提取碼:z5a7 首先找保護機制 難受 保護全開!! 執行一下,發現只有一個輸入點。 ida分析一波 發現只要滿足 v7=0x7FFFFFFFFFFFFFFFLL 還有v8=0.1 但是在

2018.12.01【SPOJ220】Relevant Phrases of Annihilation字尾陣列二分答案

傳送門 解析: 套路題。 首先串成一串求一下SA。 然後按照二分出的 l e n

2018第九屆藍橋杯省,國參賽經驗心得分享JavaB組

我來自廣東某大學,今年大一,剛剛參加完藍橋杯,這是我的第一篇部落格,希望能給你帶來一些幫助,不足之處希望指正。 關於比賽前的一些經歷:  原本想要大二才接觸這個比賽的,趕巧在2017年12月14日那天有個外校的同學跟我說他報了這個比賽,並且說服我去水一波,當時在學校的際遇

ACM-ICPC 2018 徐州賽區網路預賽G 單調佇列

傳送門 題面: There's a beach in the first quadrant. And from time to time, there are sea waves. A wave ( xx , yy ) means the wave is a rectan

Gym.102059: 2018-2019 XIX Open Cup, Grand Prix of Korea寒假gym自訓第一場

int sin 當前位置 一個 mes span 不存在 src tree 整體來說,這一場的質量比較高,但是題意也有些難懂。 E.Electronic Circuit 題意: 給你N個點,M根線,問它是否是一個合法的電路。 思路: 一個合法的電路,經過一些串聯並

BZOJ 4884 [Lydsy2017年5月月]太空貓單調DP

return 畫面 int pac logs name 左右 ring size 【題目鏈接】 http://www.lydsy.com/JudgeOnline/problem.php?id=4884 【題目大意】   太空貓(SpaceCat)是一款畫面精