刷漆
時間限制: 1 Sec 內存限制: 128 MB
題目描述
Czy 做完了所有的回答出了所有的詢問,結果是,他因爲腦力消耗過大而變得更虛了:)。幫助Czy 恢復身材的艱鉅任務落到了你的肩上。
正巧,你的花園裏有一個由 N 塊排成一條直線的木板組成的柵欄,木板從左到右依次標號 1 到 N。這 N 塊木板中,有 M 塊木板前面放着一桶油漆。油漆有不同的顏色,每種顏色可以由一個大寫字母表示(A 到 Z)。而你要求 Czy 用他的油漆刷子給柵欄刷上油漆。
已知 Czy 會選擇一個前方放有油漆桶的木板開始他的任務。刷子蘸上油漆後,他開始隨機地沿着柵欄走,他不會走出柵欄的範圍。隨機地走表示 Czy 會沿着他選擇的方向一直走,然後隨機在任何時候改變方向。沿着柵欄走只有兩個方向,向前和向後。
你發現 Czy 刷油漆的過程總是符合下列規則:
- 每個油漆桶裏裝着無限多的油漆;
- 刷子上每次只有一種顏色的油漆,每次蘸油漆都會完全替換刷子上的油漆顏色;
- 當 Czy 走到一個油漆桶前,他會首先用刷子蘸這個油漆桶裏的油漆;
- Czy 每走過一個木板都會將這個木板刷成當前刷子上的油漆顏色。
已知木板可以被多次刷上油漆,每次都會完全覆蓋之前的顏色。當所有木板都被刷上了油漆
的時候,Czy 才能停下來(當然他也可以繼續刷到他想停下來爲止)。你看着 Czy 在柵欄前來回舞
動,突然想知道 Czy 停下來的時候柵欄有多少種可能的不同油漆方案。定義當至少有一塊木板顏
色不同時,兩種油漆方案被視爲是不同的。
請你輸出不同的油漆方案數對 10^9+9 取模的值。
輸入
輸入的第一行包含兩個整數 N 和 M。
接下來 M 行,每行兩個整數 x 和 y,表示第 y 塊木板前面有一個裝着顏色爲 x 的油漆的 油漆桶。
輸出
輸出一行,包含一個整數,表示不同的油漆方案數對 109 + 9 取模的結果。
樣例輸入
6 2
A 2
B 6
樣例輸出
4
提示
對於 30% 的數據,1 ≤ M ≤ N ≤ 100。
對於 100% 的數據, 1 ≤ M ≤ N ≤ 100000。
x 是 A 到 Z 之間的大寫字母;1 ≤ y ≤ N。
解法:簡單數論
- 我們先想兩塊有不同顏色的柵欄,因爲染色是連續的,所以假設兩塊木板相隔4塊木板,顏色分別爲A和B,那麼只有三種情況,1A3B,2A2B,3A1B,然而你可能會問,不是6種嗎,爲什麼反過來不可以,反過來,你能用B染眼前的染成A確實NB
- 然後就很簡單了,我們只需要按照距離排好序,然後如果相鄰兩塊顏色不同,那我們把ans和距離相乘即可,根據乘法原理顯然成立
AC代碼
#include<cstdio>
#include<algorithm>
#include<iostream>
#define re register int
using namespace std;
struct node {
char op; int x;
}e[100010];
int n,m;
inline int read() {
int x=0,cf=1;
char ch=getchar();
while(ch<'0'||ch>'9') {
if(ch=='-') cf=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9') {
x=(x<<3)+(x<<1)+(ch^48);
ch=getchar();
}
return x*cf;
}
inline bool cmp(node a,node b) {
return a.x<b.x;
}
int main() {
n=read(),m=read();
for(re i=1;i<=m;i++) {
cin>>e[i].op;
e[i].x=read();
}
sort(e+1,e+m+1,cmp);
long long ans=1,mod=1e9+9;
for(re i=2;i<=m;i++) {
if(e[i-1].op!=e[i].op) {
(ans*=e[i].x-e[i-1].x)%=mod;
}
}
printf("%lld",ans);
return 0;
}