XSY2892 GDSOI2018 誰是冠軍

2022-05-03 15:57:25 字數 2627 閱讀 1685

為什麼noi模擬賽裡會做到省選原題啊……

有n個人,簡單起見把他們編號為1到n,每個人有三項指標分別是攻擊力,防禦力和血量。現在要進行n-1場比賽,每次在剩下的人裡面隨機地選出兩個人進行比賽,當乙個人有大於等於兩項指標嚴格大於另乙個人時,這個人獲得勝利。每次比賽,勝者留下,敗者淘汰。

現在請你求出所有可能成為冠軍(留到最後)的人。

第1行有乙個整數n,表示人數為n。

接下來n行,每行有三個整數$a_i,b_i,c_i$分別表示編號為i的人的攻擊力,防禦力和血量。

資料保證對於任意兩個人的同一項指標值不會相同。

按編號從小到大輸出有可能成為冠軍的人的編號,每行輸出乙個數。

對於$60\%$的資料$1\leq n\leq 5000$

對於$100\%$的資料$1\leq n\leq 100000$

首先60分很簡單,暴力建圖,即如果x能勝y就從x到y建有向邊,最後從每個點出發看能否遍歷整個圖就好了;

也可以tarjan縮點之後直接找入度為0的聯通塊,塊內的點就是答案;

但這樣做依然是$o(n^2)$的,複雜度瓶頸在於邊數是$o(n^2)$的,因此很容易想到線段樹優化建圖;

由於他的要求是至少兩維小於,所以可以兩兩拆開來做三遍;

那麼先把第一維排序,第二維離散化後開一顆權值線段樹,新加入乙個點i就將它連向權值在$[1,i的第二維權值-1]$內的區間;

這樣子做乙個點最多隻會連向$o(logn)$個區間,所以能過;

注意修改具有時效性,所以要邊加邊連,具體見**。

1 #include2 #include3 #include4 #include5 #include6 #include7 #include8

#define inf 2147483647

9#define eps 1e-9

10using

namespace

std;

11 typedef long

long

ll;12 typedef double

db;13

struct

edgea[20000001

];16

struct

unip[100001

];19

struct

nodet[500001

];22

int n,tot=0,tid=0,bcc=0,tim=0,cnt,rt,dfn[6000001],low[6000001],blg[6000001],head[6000001

];23

int ans[100001],anss=0

;24 stacks;

25bool

cmp(uni a,uni b)

28bool

_cmp(uni a,uni b)

31void add(int u,int

v)37

void build(int &u,int l,int

r)45

void updata(int u,int l,int r,int p,int

x)50

int mid=(l+r)/2;51

if(p<=mid)updata(t[u].ls,l,mid,p,x);

52else updata(t[u].rs,mid+1

,r,p,x);

53if(t[t[u].ls].v&&t[t[u].rs].v)else t[u].v=t[t[u].ls].v+t[t[u].rs].v;58}

59void query(int u,int l,int r,int l,int r,int

id)65

int mid=(l+r)/2;66

if(l<=mid)query(t[u].ls,l,mid,l,min(mid,r),id);

67if(mid1,r,max(mid+1

,l),r,id);68}

69void

link()

78 cnt=0

;79 build(rt,1

,n);

80//

puts("----13----");

81for(int i=1;i<=n;i++)

85 sort(p+1,p+n+1

,_cmp);

86 cnt=0

;87 build(rt,1

,n);

88//

puts("----23----");

89for(int i=1;i<=n;i++)93}

94void tarjan(int

u)else

if(!blg[v])low[u]=min(low[u],dfn[v]);

103}

104if(low[u]==dfn[u])

112}

113}

114int

main()

121 tid=n;

122link();

123for(int i=1;i<=n;i++)

127}

128for(int i=1;i<=n;i++)

131for(int i=1;i<=anss;i++)

134return0;

135 }

XSY 3327 思維 跑步

題意 給你乙個nn的網格。初始時,每個網格有乙個非負權值。有n次操作。每次操作會將乙個網格的權值加1或減1。權值操作後仍非負 輸出當前每個網格到11的最長路 每步向上或向左 的總和。n 2000 n leqslant 2000 n 2000 解法 這是一道好題!我太菜了,做不出。我們考慮維護dp值。...

XSY3904 直線(分塊)

直線 注意到題目沒有給什麼特殊的性質,除了直線隨機生成。所以考慮隨機化演算法或均攤演算法。有一種很神奇的分塊做法 考慮將整個平面分成 b b b times b b b 塊,每塊大小 109 b 10 9b dfrac times dfrac b109 b109 而且每乙個塊記錄一下有哪些直線經過它...

xsy 相似字串

輸入第1行,包含3個整數n,q。q代表詢問組數。第2行是字串s。接下來q行,每行兩個整數i和j。1 i j 輸出共q行,每行乙個數表示每組詢問的答案。如果不存在第i個子串或第j個子串,則輸出 1。關於這道題的每個詢問首先要求出第i小和第j小的子串在原串的位置,然後快速地求出這兩個子串的最長公共字首和...