[oj#40]後宮佳麗
試題描述
如果機房要關門了,或者有妹子在等你,你可以直接看最後一句話。
fyq 是乙隻飢渴的鴨子。
fyq 有乙個充實的後宮,可惜他總是體力不支,為此他經常苦惱,總是想方設法讓自己能夠泡到更多妃子。
fyq 為他的的每個妃子建立了一間屋子,屋子與屋子之間可能有一條路連線。每條路有乙個長度 len
'>len
,fyq 走過這條路時會消耗 len
'>len
的體力,但是當 fyq 進入一間屋子雲雨一翻le
n'>len
'>後,體力立刻恢復至初始值。每個妃子有乙個型別 typ
ei'>typei
,fyq 希望知道他見到次數最多的會是哪個型別,以便做更加充分的準♂備。注意,如果有見到次數並列第一的幾個型別,那麼請輸出型別編號最小的,因為 fyq 更加偏愛型別編號小的妃子。
接下來有 q
'>q
天,fyq 每天都打算找他的妃子們。第 i
'>i
天他會從妃子 x
i'>xi
的屋子出發,初始時有 w
i'>wi
的體力。你不能讓 fyq 太虛導致他無法好好享受,所以你要保證任何時刻不能讓他的體力值低於 0
'>0
。一句話題意:給你乙個 n
'>n
個節點 m
'>m
條邊的無向圖,邊有長度,點帶顏色(節點 i
'>i
的顏色為 typ
ei'>typei
);給你 q
'>q
個詢問形如 (xi
,wi)
'>(xi
,wi)
,每次你從節點 x
i'>xi
出發,只能走長度不超過 w
i'>wi
的邊,問經過的所有節點中顏色數目最多的
n
'>m
'>i
'>typ
ei'>q
'>(xi
,wi)
'>x
i'>w
i'>顏色
n
'>m
'>i
'>typ
ei'>q
'>(xi
,wi)
'>x
i'>w
i'>是哪個(如果有多個並列,輸出顏色編號最小的)。
(無向圖有可能不連通。)
輸入
第一行三個整數 n,m
,sec
ret'>n,m,secret。se
cret
'>secret
的含義待會解釋。
第二行 n
'>n
個整數,第 i
'>i
個整數表示 typ
ei'>typei
。接下來 m
'>m
行每行三個整數 u,v
,len
'>u,v,len
,表示 u
'>u
,v'>v
之間有一條長度為 len
'>len
的雙向邊。
接下來一行乙個整數 q
'>q
。接下來 q
'>q
行,每行兩個整數 xi,
wi'>xi
,wi表示 fyq 一天的計畫。se
cret
'>secret
的值域為
'>
,若 sec
ret'>secret=1
表示 fyq 比較害羞,他不肯一次告訴你接下來 q
'>q
天的所有計畫,所以他對計畫進行了加密,解密的方式 x
i'>xi
和 wi
'>wi
都異或上 las
tans
'>lastans,la
stan
s'>lastans
表示昨天的答案;如果是第一天 las
tans
=0'>lastans=0
,即第一天的資訊 fyq 沒有加密。
輸出
輸出 q
'>q
行,第 i
'>i
行乙個整數表示第 i
'>i
天的答案。
輸入示例1
5602113
2122
1342
3734
5456
5334
1122
4458
輸出示例1
2131
輸入示例2
5612113
2122
1342
3734
5456
5334
1100
55611
輸出示例2
2131
資料規模及約定
對於 20
%'>20%
的資料,1≤n
≤1000
'>1≤n≤1000
對於另外 40
%'>40%
的資料,sec
ret=
0'>secret=0
對於全部資料,1≤n
≤105'>1≤n≤105,1≤
m,q≤
2×105
'>1≤m,q≤2×105,1≤
type
i,u,
v,xi
≤n'>1≤typei
,u,v,xi
≤n,1≤l
en,w
i≤106
'>1≤len,wi
≤106
題解
我們構出 kruskal 重構樹,問題變成了求子樹內最小眾數,可以自底向上用平衡樹啟發式合併算出每個節點的子樹的答案。
關於 kruskal 重構樹可以去看一下這道題。
#include #include #include #include #include #include using namespace std;int read()
while(isdigit(c))
return x * f;
}#define maxn 100010
#define maxm 200010
#define maxlog 18
struct node
node(int _1, int _2, int _3): col(_1), val(_2), r(_3) {}
bool operator < (const node& t) const
} ns[maxn];
int tot, ch[maxn][2], fa[maxn], rec[maxn], rcnt;
int getnode()
return ++tot;
}void maintain(int o)
void rotate(int u)
node opt;
void add(int& o, int col, int val)
if(ns[o].col == col)
bool d = col > ns[o].col; opt = max(opt, ns[o]);
add(ch[o][d], col, val); fa[ch[o][d]] = o;
if(ns[ch[o][d]].r > ns[o].r)
return maintain(o);
}node set[maxn]; int cnts;
void recycle(int& o)
struct edge
edge(int _1, int _2, int _3): a(_1), b(_2), c(_3) {}
bool operator < (const edge& t) const
} es[maxm];
int pa[maxn<<1], rt[maxn<<1];
int findset(int x)
int e, head[maxn<<1], nxt[maxn<<1], to[maxn<<1], fa[maxn<<1][maxlog];
void addedge(int a, int b)
bool vis[maxn<<1];
void build(int u)
int color[maxn<<1], totc[maxn<<1], wei[maxn<<1];
int jump(int u, int w)
int main()
sort(es + 1, es + m + 1);
for(int i = 1; i < (n << 1); i++)
for(int i = 1; i <= m; i++)
} for(int i = n; i; i--) if(!vis[i]) build(i);
// for(int i = 1; i <= n; i++) printf("%d%c", color[i], i < n ? ' ' : '\n');
int q = read(), lst = 0;
for(int k = 1; k <= q; k++)
return 0;
}
東華oj 基礎題第40題
40 分拆素數和 問題描述 把乙個偶數拆成兩個不同素數的和,有幾種拆法呢?說明 比如10,可以拆成3 7和5 5以及7 3,但是3 7與7 3相同,只算一種,5 5由於兩個素數相同,不計算在內。因此,10的拆法只有一種。輸入說明 首先輸入乙個t 不超過500 然後輸入t個正的偶數,其值不會超過100...
佳弗網路競拍系統 v4 0 成熟競拍
佳弗網路競拍系統是佳弗網路工作室全力打造的一款國內做成熟競拍系統。本版本為佳弗網路工作室競拍系統非商用版本。環境需求 1.可用的 www 伺服器,如 apache zeus iis 等 2.php 4.3.0 及以上 3.zend optimizer 2.5.7 及以上 4.mysql 3.23 及...