BZOJ2375 瘋狂的塗色

2022-05-12 01:53:06 字數 1828 閱讀 5737

題目:

小t非常喜愛畫畫,但是他還是乙個初學者。他最近費盡千辛萬苦才拜到已仙逝的達 芬奇為師(神仙?妖怪?謝謝)。達文西果然是畫雞蛋長大的,讓小t一入門就拿著一張白紙條瘋狂地塗色。假設紙條被劃分成了n個區域,用1~n的整數從左到 右順序編號,達文西總共下達了m條指令。第i條指令是讓小t把編號為(i*p+q)mod n+1與(i*q+p)mod n+1(p,q為常整數)之間的區域(連續的一段區域)塗成第i種顏色。你可以假設達文西家中顏料的顏色數足夠多(達文西是畫雞蛋長大的)。

現在由於達文西下達的指令過多,小t一時應付不過來。達文西只讓他回答每乙個區域最後的顏色。趁達文西還在「五穀輪迴之所」忙碌時,小t偷偷的請讓你這個計算機高手幫他算出最後的顏色狀態,並告訴他。時間緊迫,要快喲!(達文西的指令次數多到噁心)

100%資料滿足:1≤n≤1000000,1≤m≤10000000;1≤m*p+q,m*q+p≤231-1;

題解:考慮反著刷,從m開始刷,當前被塗上色的最後一定是該顏色。塗上色的就刪去。

這讓我們想到了鍊錶,但實際上這樣也有可能跳躍很多次。

最好的辦法是並查集,類似與上帝造題的7分鐘,我們一旦某個點 i 被塗色了,就將它合併到 i+1 所在的連通塊裡。

這樣均攤下來複雜度是o(n)的

**:

1 #include2

3 #include4

5 #include6

7 #include8

9 #include10

11 #include12

13 #include14

15 #include16

17 #include

1819 #include20

21 #include

2223

#define inf 1000000000

2425

#define maxn 1000000+5

2627

#define maxm 500+100

2829

#define eps 1e-10

3031

#define ll long long

3233

#define pa pair34

35#define for0(i,n) for(int i=0;i<=(n);i++)

3637

#define for1(i,n) for(int i=1;i<=(n);i++)

3839

#define for2(i,x,y) for(int i=(x);i<=(y);i++)

4041

#define for3(i,x,y) for(int i=(x);i>=(y);i--)

4243

#define mod 1000000007

4445

using

namespace

std;

4647 inline int

read()

4849

5455

while(ch>='

0'&&ch<='9')

5657

return x*f;

5859}60

intn,m,p,q,v[maxn],fa[maxn];

61 inline int find(int x)

6263

intmain()

6465

81if(find(1)==n+1)break;82

}83 for1(i,n)printf("

%d\n

",v[i]);

8485

return0;

8687 }

view code

BZOJ 2054 瘋狂的饅頭

time limit 10 sec memory limit 162 mb submit 449 solved 175 submit status 第一行四個正整數n,m,p,q 一共輸出n行,第i行表示第i個饅頭的最終顏色 如果最終顏色是白色就輸出0 4 3 2 422 30並查集。一看這道題認為...

bzoj 2054 瘋狂的饅頭

想到了要用一種東西維護下乙個沒被染色的是什麼東西,但是沒想到是並查集。這道題就相當於在每乙個集合裡的數都會跳到乙個相同的點,就相當於並查集的代表元素。如果將乙個點染色,就把它的父親設為i 1,這樣並查集的代表元素就是下乙個沒有被染色的點。include include include include...

BZOJ2054瘋狂的饅頭

2054 瘋狂的饅頭 第一行四個正整數n,m,p,q output 一共輸出n行,第i行表示第i個饅頭的最終顏色 如果最終顏色是白色就輸出0 首先考慮資料範圍,區間修改的話用線段樹對於10 7的資料肯定會t掉,所以需要乙個優化的演算法。由於求最後的染色,所以可以用並查集。怎麼用呢。從後往前列舉,如果...