10 4 NOIP模擬賽 線段樹 DP Trie

2021-08-09 00:08:15 字數 4422 閱讀 1399

考慮到只有26個字母, 所以區間排序相當於就是把1-26的值從大到小或者從小到大一次區間賦值. 線段樹即可. 當然用平衡樹套一下的話就沒有26這個常數了. 當然有一位神犇kechan不加讀優只用線段樹一樣跑在0.5s以內.

kechan的極優**.

#include

#include

#include

#include

using

namespace

std;

const

int n=1e5+5;

int n,m;

char ch[n];

int getid(char x)

struct tree;

void tree_mod(tree *nd,int lef,int rig,int l,int r,int *tem,int dowhat);

struct tree

void pus(int lef,int rig)

}pool[n<<2],*root,*tail=pool;

tree *tree_bui(int lef,int rig)else

return nd;

} void tree_mod(tree *nd,int lef,int rig,int l,int r,int *tem,int dowhat)

if(tot>las)

}}else

if(tot>las)

}}

}else

}void tree_que(tree *nd,int lef,int rig,int l,int r,int *tem)else

}void tree_pri(tree *nd,int lef,int rig)else

}else

if(lef==rig)

}else

}int main()

tree_pri(root,1,n);

return0;}

/*5 2

cabcd

1 3 1

3 5 0

*/

本蒟蒻的的**.

這道題題面有問題, 他沒有說中間不在給定區間的空位置不能填…比如樣例第一行第3個點取0, 1都可以. 方案就不止12種.

這道題dp方程很奇妙, 可以說成基於未來狀態上的dp. dp[i][j]表示當前處理到第i列, 有j個 左端點在i之前的 右區間沒有處理(所謂處理就是在指那個區間某個位置選乙個1), 所可能的合法方案數. 那麼答案就是dp[m][0].

由於是j個右區間沒有處理, 那麼也就是說右端點在i之前的左區間都要處理. 我們設當前左端點在i這個位置上的右區間有cr個, 右端點在i上的左區間有cl個. 那麼如果當前有j個右區間沒處理. 那麼:

dp[i][j + cr] 就可以從 dp[i -1][j]轉移過來. 因為要首先把右端點在i上的左區間給處理了, 那麼i之前有i - s[i-1] + j個地方可以選(本身有i 個地方可以選, s[i-1]指的是端點在i-1及之前的所有區間, 我們假設都處理了, 那麼每個區間恰好用1個1, 那麼可以選的就是i-s[i - 1], 因為實際上我們有j個沒有處理, 那麼就是還要加個j. 那麼方案數就是i - s[i - 1] + j 裡選cl個的排列(順序不一樣是不同的方案).

那麼轉移方程就是:

dp[i][j + cr[i]] = (dp[i][j + cr[i]] + dp[i - 1][j] * nott % mod) % mod; nott就是上面那個排列.

然後這是cr個右區間都不處理, 要是處理1個的話.

dp[i][j + cr[i] - 1] = (dp[i][j + cr[i] - 1] + dp[i - 1][j] * didd % mod * (j + cr[i]) % mod) % mod;

dp[i][j+cr[i] - 1]之前是有可能更新過的.

解釋一下轉移, 因為當前處理乙個的話因為都是左端點在i之前的, 所以處理乙個的話, 就要佔乙個位置, 所以處理cl的時候就變成i - 1 - s[i-1] + j裡選cl個. 然後cr個裡面選1個處理就是(j + cr)裡選乙個的方案.

即可.對方那個操作就是左移一位, 若x左移一位有1越過2^n就把那個1調到末尾. 所以n = 2時, 3左移1位還是11 – 3. 那麼x在異或i個數之後再左移一位其實等價於先左移一位然後將i個數也左移一位, 異或了之後, 再普通的異或後面的即可. 那麼預處理出每前i個數左移一位異或再異或後面得到的數即可. 這樣有m+1個. 那麼就是選乙個數讓與這m+1個數其中的乙個最大異或最小. 建乙個tyie樹貪心即可, 非常簡單的dp.

#include

const int maxn = 4000000;

int n, m, id, root, a[100005], b[100005];

int c[maxn][2], big[maxn], num[maxn];

inline void insert(int &rt, int who, int

pos)

inline int ca(int

x)void dfs(int rt, int

pos)

if(!c[rt][0])

if(!c[rt][1])

dfs(c[rt][0], pos - 1), dfs(c[rt][1], pos - 1);

if(big[c[rt][1]] > big[c[rt][0]])

big[rt] = big[c[rt][1]], num[rt] = num[c[rt][1]];

else

if(big[c[rt][0]] > big[c[rt][1]])

big[rt] = big[c[rt][0]], num[rt] = num[c[rt][0]];

else big[rt] = big[c[rt][0]], num[rt] = num[c[rt][0]] + num[c[rt][1]];

}int main()

NOIP模擬賽 天神下凡 動態開點線段樹

這些圓一定是在同一水平面上的,由於他們沒有相交,因此我們發現他們每個人與外界關係可以分為,1.存在並圈圈 2.存在圈圈並被割,因此我們把所有的圓都加1,把被割的在加1,就可以啦,因此我們開乙個線段樹,維護一段區間有沒有被全部覆蓋 include include include include inc...

noip模擬賽(一)魔法樹

魔法樹 mahou.pas c cpp 問題描述 魔法使mored在研究一棵魔法樹。魔法樹顧名思義,這貨是一棵樹 奇葩的是魔法樹上的每一條邊都擁有乙個魔法屬性 如果不那麼奇葩就不是mored的魔法樹了。魔法使mored在研究這棵魔法樹的方法比較奇葩,每一次他會選擇一條路徑 施法。這個魔法是mored...

省選模擬賽 4 26 T1 dp 線段樹優化dp

算是一道中檔題 考試的時候腦殘了 不僅沒寫優化 連暴力都打掛了。容易發現乙個性質 那就是同一格仔不會被兩種以上的顏色染。顏色就三種.通過這個性質就可以進行dp了.先按照左端點排序。設f i 表示前i個畫筆必選的最大價值。列舉決策j 分類討論相交還是包含 還是相離。其中包含的情況沒必要討論 相交需要比...