XIN隊演算法

注:名稱由莫隊演算法改編而來

從luogu搬過來了。。。

\(newly\;upd:2021.7.8\)

\(newly\;upd:2021.6.6\)

OI至高演算法,只要XIN隊演算法打滿,保證所有比賽 \(rk1\),碾爆標程,讓對手望塵莫及。

請慎用

XIN隊演算法:

1.遇到不會做的題目不用慌,你要想到你還有XIN隊演算法,仔細讀題,理解題目意義,然後開始準備寫XIN隊演算法。

2.這時候,你可以瀟灑地敲出:

void xin_team()

然後開始暴搜

XIN隊演算法框架:

    void xin_team(引數)
{
if(邊界) return;
for(register int i=1;i<=n;++i)
if(條件1)
{
狀態轉移
xin_team(引數);
狀態回溯
}
}

但是,對於不同的題目, void xin_team 並不能解決所有的題目,那該怎麼辦呢???

對於很多不能用XIN隊\(1\)號演算法的,大多數可以使用XIN隊\(2\)號演算法:

next_permutation(a+1,a+n+1); 大法

框架:


void xin_team2
{
do
{
答案記錄
}while(next_permutation(a+1,a+n+1));
}

非常完美

但是,由於XIN隊演算法時間複雜度 只有 \(\mathcal O(2^n)\)或者是\(\mathcal O(n!)\),所以我們提出優化:

優化XIN隊演算法:

非常不建議使用

框架:

        srand((unsigned)time(0));
do
{
random_shuffle(a+1,a+n+1);
答案記錄
}while(next_permutation(a+1,a+n+1));

複雜度:

\[\mathcal O(\lim_{1\to\infty})
\]

還附加超大常數

XIN隊演算法升級:二維XIN隊

有很多很多的題目無法用普通的\(XIN\)隊演算法解決,這時候我們就需要\(XIN\)隊演算法升級版:\(\color{red}\huge_{\text{二維XIN隊}}\)

二維\(XIN\)隊對於程式碼能力的提升是顯而易見的,然而對複雜度的提升更是顯而易見的,二維\(XIN\)隊演算法框架:

比方說:

[SDOI2015]排序

使用此演算法,輕鬆 \(30pts\)

	void xin_team2(int x,int now)
{
if(邊界)
{
xin_team2(x,now);
記錄
return ;
}
for(register int i=1;i<=n;++i)
{
記錄狀態
xin_team(x,now+1);
回溯狀態
}
}
void xin_team1(int x,int now)
{
if(邊界)
{
xin_team2(x,now);
記錄
return ;
}
for(register int i=1;i<=n;++i)
{
記錄狀態
xin_team(x,now+1);
回溯狀態
}
}

複雜度:

\[\mathcal O(n! * 2^n)
\]

並且只能說是大概

我們發現,對於一般的題目,大多是 \(dp\) 解決,然而純粹運用上述方法只能拿到部分分數,甚至全部 \(TLE\) 所以,記憶化 \(XIN\) 隊演算法應運而生。


對於優秀的記憶化 \(XIN\) 演算法,想要什麼狀態就去找什麼狀態,然後就可以實現飛一般的提升。。。

包準快

使用記憶化 \(XIN\) 隊演算法,\(NOI\)包準不打鐵!

比方說這個題: \(NOI2020\)美食家

使用 \(XIN\) 隊演算法,輕輕鬆鬆 \(40pts\)

框架:

	void xin_team(int i,int j)
{
if(f[i][j]) return f[i][j];
for(k ...)
xin_team(k,~);
return f[i][j];
}

演算法的時間複雜度就是:

\[\mathcal O (\prod_{i=1}^{n} state_{num_i})
\]

\(num\)為狀態,複雜度總體海星。。。

然而:

\(\color{red} \huge{\text{方程推不出}}\)

\(\color{green} \huge{\text{親人兩行淚}}\)





\(XIN\) 優化分塊預處理

一個月沒更了,這次在刷題的時候發現了最新的 \(XIN\) 隊演算法應用

這是在寫蒲公英的時候發現的。

做了好長時間,中途還跑去做樹鏈去了。



時間相差的確實長了一些。。。

在用分塊解決這個問題的時候。

發現狂 \(T\) 不止。

但是。

不知道為什麼在其他的 \(OJ\) 上都可以過掉

只不過就是很慢。

但是在學校的 \(OJ\) 上最多隻有 \(70pts\)。

好評測機

然而並不敢找老師去開大時限

所以我只能優化暴力。。。

然後。

我發現在預處理 \(p_{i,j}\) 的時候,時間差的很多很多。

然而如果用 \(query\) 函式而不是暴力去搞就會錯。。。

因為有些需要的狀態還沒有附上值但是接下來處理需要用到。。。

所以我集中生智

發現了 \(XIN\) 隊優化分塊預處理法

我都沒想到 \(XIN\) 隊演算法還有優化別的東西的一天

主要思想就是 缺啥找啥

然後狀態就有了。。。

雙指標突然不香了 \(\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\) --搖擺兵

然後飛快

	void xin_team(int x,int y)
{
if(p[x][y]) return;
if(abs(y - x) <= 2) {p[y][x] = p[x][y] = query(l[x],r[y],0); return;}
xin_team(x+1,y-1);
p[x][y] = p[y][x] = query(l[x],r[y],0);
}

\(\color{red}{\huge{\uparrow \text{精華}}}\)

\(\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\huge{record}\)