顯示具有 CodeChef 標籤的文章。 顯示所有文章
顯示具有 CodeChef 標籤的文章。 顯示所有文章

2016年3月12日 星期六

[CodeChef XORSACK]Hououin Kyouma and Xorsack

中文版

The problem source is not easy to find, so the problem link is provided.

Definitions:
"A number set" is a set of numbers, "Number sets" means a lot of sets of numbers
"$bit_{i}$" is the $i$-th $bit$ of a number or $\oplus($elements of a number set$)$ ($\oplus$ is the sign of $XOR$)
"$X_{i}$" is number $X$'s $bit_{i}$ ($X$'s $i$-th $bit$)

One $bit$ by one $bit$, we can try maintain the number sets satisfy current conditions.

But the number of number sets is too large ($2^N$)!
What can we do?
It doesn't matter, we can save these $N$ numbers. (call it $s$, $s$ can represent all $2^N$ number sets)
At least later we still can get all the number sets, by enumerate "to choose or not to choose"(call it "choosing state") of each elements of $s$.

The first step is maintain all the number sets, whose $bit_{1}=K_{1}$.

Suppose that $K_{1}=0$
We can know, whether we choose each number (in $s$), whose $bit_{1}=0$, does not matter.
The key point is, how to pick up all the number sets, which has even number of elements satisfy $bit_{1}=1$. ($bit_{1}$ of all the number sets would $=0$ only if we do this)
Consider all elements (in $s$), whose $bit_{1}=1$, $v_{1},v_{2},v_{3},...,v_{n}$
We can prove that $s'=\{v_{1}\oplus v_{2},v_{2}\oplus v_{3},v_{3}\oplus v_{4},...,v_{n-1}\oplus v_{n}\}$ can exactly represent all number sets that contain even number of elements, whose $bit_{1}=1$ (Why? Maybe you could figure out by yourself :))

So, what we should do is replace $s$ with $\{{elements\ (in\ original\ s),\ whose\ bit_{1}=0},s'\}$
Then, we can continue to maintain all the number sets, satisfy $(bit_{i}=K_{i},\forall 1\leq i\leq 2)$, $(bit_{i}=K_{i},\forall 1\leq i\leq 3)$..., and so on!

What if $K_{1}=1$?
We can know, whether we choose each number (in $s$), whose $bit_{1}=0$, does not matter.
The key point is, how to pick up all the number sets, which has odd number of elements satisfy $bit_{1}=1$. ($bit_{1}$ of all the number sets would $=1$ only if we do this)
Consider all elements (in $s$), whose $bit_{1}=1$, $v_{1},v_{2},v_{3},...,v_{n}$
We just know that $s'=\{v_{1}\oplus v_{2},v_{2}\oplus v_{3},v_{3}\oplus v_{4},...,v_{n-1}\oplus v_{n}\}$ can exactly represent all number sets that contain even number of elements, whose $bit_{1}=1$
Why not make each number sets, which originally doesn't contain $v_{1}$, contains $v_{1}$,
and make each number sets, which originally contains $v_{1}$, does not contains $v_{1}$?

Therefore, what should we do was just replace $s$ with $\{\{$elements (in original $s$), whose $bit_{1}=0\},s'$ after modify its $v_{1}$'s choosing state$\}$
Then, we can continue to maintain all the number sets, satisfy $(bit_{i}=K_{i},\forall 1\leq i\leq 2)$, $(bit_{i}=K_{i},\forall 1\leq i\leq 3)$..., and so on!

The problem is, how to modify all number sets' $v_{1}$'s choosing state in $s'$?
We can know that choosing the same number twice, has the effect equals to not to choose the number.
Therefore, we just force it to choose an extra number, $v_{1}$.
For implementation, just let $K\oplus v_{1}$! (But I use another variable, $now$, to represent the changes of $K$)

The answer is $No$ if $v_{1}$ does not exist when we need it.
Or there's nothing going wrong until the last $bit$ is considered (That means there are still number sets satisfy the conditions), the answer is $Yes$

Time complexity: $O(31N)$ (My code enumerates $31$ $bit$s)

code:

[CodeChef XORSACK]Hououin Kyouma and Xorsack

English version

這題目不好找,附上題目連結

說明:
$bit_{i}$為某數字或某數字集合$\oplus$起來的數字,它的第$i$個$bit$ ($\oplus$為$XOR$的符號)
$X_{i}$為數字$X$的$bit_{i}$

我們可以嘗試一個$bit$一個$bit$慢慢維護符合目前條件的數字集合們

可是數字集合的數量實在太多了 ($2^N$),該怎麼辦呢?
沒關係,我們先存下這$N$個數字 (稱$s$,$s$代表了這$2^N$種數字集合),這樣至少以後會知道枚舉$s$裡面每個數字的選或不選就可以得到每一種數字集合

第一步就是維護出所有會讓$bit_{1}=K_{1}$的數字集合

假設$K_{1}=0$
我們知道,$s$中$bit_{1}=0$的那些數字選或不選都沒有影響
重點是要怎麼挑出那些包含偶數個$bit_{1}=1$的數字的集合 (因為這樣它們的$bit_{1}$才會$=0$)
考慮$s$中$bit_{1}=1$的數字為$v_{1},v_{2},v_{3},...,v_{n}$
可以證明,$s'=\{v_{1}\oplus v_{2},v_{2}\oplus v_{3},v_{3}\oplus v_{4},...,v_{n-1}\oplus v_{n}\}$恰可以代表所有選擇偶數個$bit_{1}=1$的數字的集合!(想一想,為甚麼XD)

因此,我們只要將$s$取代成$\{{原本s裡面bit_{1}=0的數字},s'\}$,就可以繼續維護$(bit_{i}=K_{i},\forall 1\leq i\leq 2)$、$(bit_{i}=K_{i},\forall 1\leq i\leq 3)$...的數字集合!

如果$K_{1}=1$呢?
我們知道,$s$中$bit_{1}=0$的那些數字選或不選都沒有影響
重點是要怎麼挑出那些包含奇數個$bit_{1}=1$的數字的集合 (因為這樣它們的$bit_{1}$才會$=1$)
考慮$s$中$bit_{1}=1$的數字為$v_{1},v_{2},v_{3},...,v_{n}$
剛剛我們知道了,$s'=\{v_{1}\oplus v_{2},v_{2}\oplus v_{3},v_{3}\oplus v_{4},...,v_{n-1}\oplus v_{n}\}$恰可以代表所有選擇偶數個$bit_{1}=1$的數字的集合
那麼,把所有沒選到$v_{1}$的集合改成有選到$v_{1}$,選到$v_{1}$的集合改成沒選到$v_{1}$就好了!

因此,我們只要將$s$取代成$\{\{原本s裡面bit_{1}=0的數字\},修改v_{1}選擇狀態後的s'\}$,就可以繼續維護$(bit_{i}=K_{i},\forall 1\leq i\leq 2)$、$(bit_{i}=K_{i},\forall 1\leq i\leq 3)$...的數字集合!

問題來了,要怎麼修改$s'$中所有集合的$v_{1}$選擇狀態?
我們知道,同一個數字選兩次等於沒選
因此,我們就強迫多選一個數字$v_{1}$,實作上將$K\oplus v_{1}$就好了!(不過我是另外用一個變數$now$來儲存$K$的變化)

當發現需要$v_{1}$它卻不存在時,答案為$No$
否則如果算到最後一個$bit$仍然還沒出錯 (代表還是存在符合條件的數字選擇方案),答案為$Yes$

時間複雜度:$O(31N)$ (枚舉了$31$個$bit$)

code:

2016年1月16日 星期六

[HOJ 300][Codechef]Party Invitation

HOJ生病惹QQ,因此我在這裡做了題目備份,請參考~

這題我漏考慮了圖不連通的情況卡了一小時QAQ

假設圖是連通的
先把這張圖當有向圖來看,可以發現,由於每個點最多也只能連一條邊出去,因此整張圖就一定會有一個環,然後旁邊有可能有小樹枝指向這個環(指出去的小樹枝是不可能的,因為這樣環上的點就需要兩條出邊了)
找環的方式很簡單,只要隨便找一個點,順著唯一的有向邊走,當走到重複的一個點時,就可以把這點當環的起點了

先來講點題外話
這題就是要問你一張圖有幾種獨立集
獨立集是甚麼?就是一個點集,在圖上沒有一條邊兩端點都在這個點集裡面

如果題目給的圖是一棵樹,獨立集數量要怎麼算呢?
轉成有根樹後,我們可以使用Dfs+記憶化搜索,令DP[u][c]為根節點為u的這棵子樹的獨立集數量,c=0代表u不能選進獨立集,c=1代表u一定要選進獨立集
因此,我們得到轉移式:
DP[u][0]=Pi{DP[v][0]+DP[v][1],v是u的子節點}(Pi是把每個東西乘起來的結果)
DP[u][1]=Pi{DP[v][0],v是u的子節點}

如果題目給的圖是一個環,獨立集數量要怎麼算呢?
先把環的每個點依序存到CYC裡面
令DP[u][l][r]為從CYC[0~u]裡面選出獨立集的數量,l代表CYC[0]要不要選進獨立集,r代表CYC[u]要不要選進獨立集
一開始,可以先知道DP[0][0][0]和DP[0][1][1]都是1,DP[0][0][1]和DP[0][1][0]都是0
那麼u>0時就可以得到轉移式:
DP[u][l][0]=DP[u-1][l][0]+DP[u-1][l][1]
DP[u][l][1]=DP[u-1][l][0]
最後,答案就是DP[N-1][0][0]+DP[N-1][0][1]+DP[N-1][1][0](N是環的大小)

疑真巧,這題給的圖剛好就是環上面接幾棵樹耶XD
那就來對環作DP吧
先把環的每個點依序存到CYC裡面
為了方便說明,TREE[u][c]代表接到CYC[u]上面的這棵樹裡面選出獨立集的數量,c代表CYC[0]要不要選進獨立集
TREE[u][c]怎麼算上面說過了XD
令DP[u][l][r]為從CYC[0~u]以及「接到這些點上面的樹」裡面選出獨立集的數量,l代表CYC[0]要不要選進獨立集,r代表CYC[u]要不要選進獨立集
一開始,可以先知道DP[0][c][c]是TREE[0][c],DP[0][0][1]和DP[0][1][0]都是0
那麼u>0時就可以得到轉移式:
DP[u][l][0]=TREE[u][0]*(DP[u-1][l][0]+DP[u-1][l][1])
DP[u][l][1]=TREE[u][1]*DP[u-1][l][0]
最後,答案就是DP[N-1][0][0]+DP[N-1][0][1]+DP[N-1][1][0](N是環的大小)

這題實作上沒有甚麼特別複雜的地方,code也很容易寫得出來,傳上去也WA了(?)
咦?
還記的我開頭講甚麼嗎?
這張圖不一定連通!XD

因此,分別將每個連通子圖(可以用並查集判斷)的獨立集數量算出來後,相乘就是答案了(因為它們互相獨立)
喔還有,要記的開long long和模1000000007

code: