Hnoi2018 遊戲 拓撲排序

2021-08-20 00:12:28 字數 2251 閱讀 1010

一次小g和小h在玩尋寶遊戲,有n個房間排成一列,編號為 1,

2,..

.,n 1,2

,...

,n

,相鄰的房間之間都有一道門。其中一部分們上鎖(因此需要有對應的鑰匙才能開門),其餘的門都能直接開啟。現在小g告訴了小h每把鎖的鑰匙在哪個房間裡(每把鎖鎖有且只有一把鑰匙與之對應),並作出p次指示:第i次讓小h從第 si

s

i個房間出發到 ti

t

i個房間裡。但是小g有時會故意在指令中放入死路,而小h也不想浪費多餘的體力去嘗試,於是想事先調查清楚每次的指令是否會存在一條通路。

先把直接連通的縮成乙個點,對於每乙個詢問,我們可以乙個個地拓展,但是時間上面過不去。考慮如果拓展到的這個區間已經被拓展過了,就可以合併答案了。於是我們想要新拓展到的每乙個區間都要在之前被拓展過,即乙個區間不可以被重複拓展。考慮一扇門,若鑰匙在右邊,則從左邊不可能到達右邊,從右邊遊客可能到達左邊,所以左邊必須先拓展,從左邊向右邊連一條邊拓撲排序即可。

發現很多人的部落格中分析的時間複雜度都是o(

n)o (n

),但是嚴格來說並不是的,因為每個區間可能會被訪問不止一次,但每乙個鑰匙至多只會被使用一次去將一扇新的門開啟,即至多會進行m次區間合併,所以時間複雜度為o(

n+m)

o (n

+m)。

好像還可以用記憶化搜尋去做,即遇到乙個未拓展的區間就將它拓展的結果記下來。雖然本質上是一樣的,但是我覺得記憶化搜尋更好理解。

總的來說,一道非常好的題目。

/**************************===

* author : ylsoi

* problem : game

* algorithm : tuopu_sort

* time : 2018.5.15

* **************************/

#include

#include

#include

#include

#include

#include

#include

using

namespace

std;

void file()

#define rep(i,a,b) for(register int i=a;i<=b;++i)

#define drep(i,a,b) for(register int i=a;i>=b;--i)

#define mrep(i,x) for(register int i=beg[x];i;i=e[i].last)

#define mem(a) memset(a,0,sizeof(a))

#define ll long long

#define inf int_max

#define pii pair

#define lp first

#define rp second

template

bool chkmax(t &_,t __)

template

bool chkmin(t &_,t __)

const

int maxn=1e6+10;

int n,m,p,key[maxn],degree[maxn];

int num[maxn],cnt;

pii b[maxn];

int beg[maxn],cnt_e;

struct edgee[maxn];

void add(int u,int v)

void cal(int id)

if(key[r]>=l && key[r]<=r)

if(!flag)break;

}b[id].lp=l;

b[id].rp=r;

}queue

qu;int main()

key[0]=-1;

key[n]=n+1;

rep(i,1,n)

num[i]=cnt;

}b[cnt].rp=n;

rep(i,1,cnt)

if(r!=n && key[r]>r)

}rep(i,1,cnt)

if(!degree[i])

qu.push((int)i);

while(qu.size())

cal(u);

}rep(i,1,p)

return

0;}

HNOI2018尋寶遊戲

題解我們首先按位考慮。如果有一位最終的結果為1,那麼我們可以把樹的序列看成乙個二進位制數,先出現的在底位,後出現的在高位,操作序列也可以看做乙個二進位制數,and 為1,or 為0,先出現的在低位,後出現的在高位。首先操作序列是不可能把0變成1的,那麼要使最後的結果為1,就得考慮數字序列最高位的1,...

題解 HNOI 2018尋寶遊戲

洛谷 bzoj連題面都不貼 題面 題目概述 給定n nn個長為m mm的01串,q qq次詢問,每次給定乙個長為m mm的目標串,求有多少種在n nn個串間填 位與 和 位或 符的方法使得最終計算結果為目標串 考試時忘記拼接程式了 o 對於10 10 10 的部分分可以o q 2n o q cdot...

心情 HNOI2018遊記

day 0.全機房的人好像都在做題。然而下午是社團節的遊園會,身為社幹的我風風雨雨在外面各種搬凳子搬椅子換場地招待外校同學 就這樣我好像什麼都沒有複習。晚上就一起去酒店了。大概因為是高一的緣故,並沒有非常的緊張。住進了酒店,滿腦子都是和豆豆 ww3113306 如何吃吃吃玩玩玩。非常開心的擺了一晚上...