NOIP模擬賽8 16 C 長跑(LCT)

2021-09-26 06:03:57 字數 3060 閱讀 3745

記憶體限制:128 mib

時間限制:1000 ms

【題目描述】

某校開展了同學們喜聞樂見的陽光長跑活動。為了能「為祖國健康工作五十 年」,同學們紛紛離開寢室,離開教室,離開實驗室,到操場參加 3000 公尺長跑運 動。一時間操場上熙熙攘攘,摩肩接踵,盛況空前。 為了讓同學們更好地監督自己,學校推行了刷卡機制。 學校中有 n 個地點,用 1 到 n 的整數表示,每個地點設有若干個刷卡機。 有以下三類事件: 1、修建了一條連線 a 地點和 b 地點的跑道。 2、a 點的刷卡機台數變為了 b。 3、進行了一次長跑。問乙個同學從 a 出發,最後到達 b 最多可以刷卡多少 次。具體的要求如下: 當同學到達乙個地點時,他可以在這裡的每一台刷卡機上都刷卡。但每台刷 卡機只能刷卡一次,即使多次到達同一地點也不能多次刷卡。 為了安全起見,每條跑道都需要設定乙個方向,這條跑道只能按照這個方向 單向通行。最多的刷卡次數即為在任意設定跑道方向,按照任意路徑從 a 地點 到 b 地點能刷卡的最多次數。

【輸入描述】

輸入的第一行包含兩個正整數 n,m,表示地點的個數和操作的個數。 第二行包含 n 個非負整數,其中第 i 個數為第個地點最開始刷卡機的台數。 接下來有 m 行,每行包含三個非負整數 p,a,b,p 為事件型別,a,b 為事件 的兩個引數。 最初所有地點之間都沒有跑道。 每行相鄰的兩個數之間均用乙個空格隔開。表示地點編號的數均在 1 到 n 之間,每個地點的刷卡機台數始終不超過 10000,p=1,2,3。

【輸出描述】

輸出的行數等於第 3 類事件的個數,每行表示乙個第 3 類事件。如果該情況 下存在一種設定跑道方向的方案和路徑的方案,可以到達,則輸出最多可以刷卡 的次數。如果 a 不能到達 b,則輸出-1。

輸入樣例:

9 31

10 20 30 40 50 60 70 80 90

3 1 2

1 1 3

1 1 2

1 8 9

1 2 4

1 2 5

1 4 6

1 4 7

3 1 8

3 8 8

1 8 9

3 8 8

3 7 5

3 7 3

1 4 1

3 7 5

3 7 3

1 5 7

3 6 5

3 3 6

1 2 4

1 5 5

3 3 6

2 8 180

3 8 8

2 9 190

3 9 9

2 5 150

3 3 6

2 1 210

3 3 6

輸出樣例:

-1

-180

170180

170190

170250

280280

270370

380580

感覺好lct啊。。。

先考慮乙個簡單的問題:

如何在乙個支援加邊的圖中維護兩點的連通性?

這不無腦並查集嗎。。。

再考慮乙個『簡單』的問題:

如何在乙個支援加邊的圖中維護兩點是否在同乙個邊雙連通分量?

似乎不會。。。

發現形成的第乙個邊雙連通分量一定是乙個環

想了一下,發現可以用lct+兩個並查集

先用乙個並查集check來維護連通性

再用乙個並查集real來維護邊雙連通分量的集合

如果u,v不連通,就把它們在check上合併

如果u,v連通但不在乙個邊雙連通分量,就把它們在lct上的路徑spilt出來,把路徑上的點乙個乙個在real上合併

感覺會t,於是我們縮一下點,把已經合併了real的點從lct中刪掉,只保留它們的祖宗,祖宗要統計它們的所有資訊

如果u,v在同乙個邊雙連通分量裡,就不管了

讓我們回到這個題,我們任務的就是求兩點路徑的點權和+兩點路徑上的邊雙連通分量總點權和

我們就可以用上面的思路來維護邊雙連通分量的點權和

於是我們維護的就是乙個由邊雙連通分量祖先構成的lct

如圖:

如果在已刪除節點之間連邊,就會使兩個邊雙祖先合併,就會刪掉其中之一

所以不同祖先的已刪除節點都無連邊。

**實現還有許多細節:

#include#include#includeusing namespace std;

#define n 100005

int n,m,val[n],a[n];//a是實際點權,val是祖先點權

struct node

int find(int x)

void uni(int x,int y)

}real,check;

int fa[n],ch[n][2],sum[n];

bool rev[n];

inline bool pdc(int x)

inline bool pdr(int x)

inline void pushdown(int x)

}void update(int x)

inline void rot(int x)

void pdpath(int x)

inline void splay(int x)

inline void access(int x)

}inline void beroot(int x)

inline void link(int x,int y)

void dfs(int &u,int d)//dfs只找lct上的節點(即未刪除節點)

int main()

else

} else if(op==2)

else

u=real.find(u);v=real.find(v);

beroot(u);access(v);splay(v);

printf("%d\n",sum[ch[v][0]]+val[v]);

} }}

好久都沒寫lct了。。。

jzoj 2016 5 14noip模擬賽C 總結

久違的noip模擬賽 先看第一題,dp想了一下複雜度太高,貪心的話八成會有反例 算了不糾結第一題了,先瞄一眼其他題 然後看第二題,咦矩形是什麼?懵了三秒,論智商的重要性 矩形怎麼判來著?又懵三秒 哦哦原來是送分題啊,那看第三題 嗯.覺得是先求每一行拿k個的最大價值,然後再去揹包這nm個貨物,使得其總...

2017 04 02 NOIP 普及組 模擬賽C組

總結 本次比賽310分 on3 呵呵呵呵 首先,一開始,開啟題目,發現b組可以迅速ac1題,但還是怕怕,慫回c組。8點30分,毫無頭緒地刷第2題。突然發現可以尋找中位數的方法去尋找士兵集合的那一列。9點30分,找出規律 士兵在同一列時如何站一列 10點,刷出t1和t2。t1是之前有過印象,於是純模擬...

2019 06 09 NOIP普及組 模擬賽C組

超連結為pdf題面,請先登入。渣題用s來表示長城的長度,t來表示目前的所用的時間。不斷地讀入a,b,t,而t不斷地加 b a 1 t,表示這一段所用的時間。最後s不斷減掉 bi ai 1,則就是剩下的長度了。最後t還要加上加上s1,計算普通的長城的時間。bas code include int s,...