題目:
小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 #include2view code3 #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 }
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掉,所以需要乙個優化的演算法。由於求最後的染色,所以可以用並查集。怎麼用呢。從後往前列舉,如果...