CTSC2012 熟悉的文章

2021-08-18 16:45:28 字數 1470 閱讀 7348

哈哈哈哈第一次做ctsc的題超開心,感覺一下子就有檔次了許多。

這題的資料範圍對我這種不會算空間的蒟蒻就是個迷。

對於 100%的測試資料,輸入檔案的長度不超過 1100000 位元組

呵。做法:

①把所有作文庫連起來,每兩個中間用2隔開建sam

②作文串在sam上跑一跑,計算出以每乙個位置為結尾,最多能匹配多長。即,val[i]表示,s[1…i]中與作文庫能匹配的最長suffix的長度。

③由於這題的答案具有可二分性,所以二分乙個答案l進行檢驗。用dp去求最長覆蓋數即可(單調佇列優化一下)。

這裡給出使用單調佇列的充分性的證明:即是要證i-val[i]單調不減。

=> i + 1 - val[i + 1] ≥ i - val[i]

=> val[i + 1] ≤ val[i] + 1 顯然成立

這題我tle了一整天,愣是卡在90分。人家網上別的程式,最長時間的樣例才100多ms,我不算t的點,最大的就有將近700ms。反省了很久,發現是memset的鍋。我給單調佇列清了0,這樣做完全沒有必要。但是我是真的沒想到會這樣。畢竟dp就是乙個o(n)的,memset也是o(n)。這啟發我們,盡量想清楚再決定寫不寫有沒有意義。

code:(放心看吧,網上的幾組hack資料hack不掉我)

#include #include #define n 2300010

#include using namespace std;

int n, m; char s[n];

int ch[n][3], len[n], link[n];

int last, sz;

inline void sam_init()

inline void sam_extend(int c)

} last = cur;

}int val[n], f[n], q[n];

inline bool check(int x, int len1)

while(head <= tail && q[head] < i - val[i]) ++head;

if(head <= tail) f[i] = max(f[i], f[q[head]] - q[head] + i);

} return 10 * f[len1] >= 9 * len1;

}inline int read()

while(ch >= '0' && ch <= '9')

return x * f;

}int main()

for(int i = 1; i <= n; ++i)

val[i] = cur; r = max(r, val[i]);

} while(l <= r)

else r = mid - 1;

} printf("%d\n", ans);

} return 0;

}

CTSC2012 熟悉的文章

題目 好題啊 sam 單調佇列優化 dp 首先這個 l 滿足單調性真是非常顯然我們可以直接二分 二分之後套乙個 dp 就好了 設 dp i 表示到達 i 位置熟悉的文章的最大長度 有乙個非常顯然的 dp 方程 dp i max i j mid 同時 j 1,i 這個子串也得是模式串裡的乙個子串 對於...

ctsc2010 星際旅行

題意很簡單 給定一棵樹,問從根分別走到每個節點的最長路程,其中每個點給定lim,即最多從該點出發lim次,保證lim大於等於該點的度數。特別 鳴謝 ldl在他的模擬題中出了這道題。當題解講這要用樹形dp解網路流模型時,都被驚異了,完全沒有想到網路流,也完全沒有必要網路流,atm在考場上直接有樹形dp...

CTSC2018 混合果汁

為何要用整體二分,整體二分應該怎樣二分,和 poi2011 met meteors十分相像,這裡就不再重複。那麼對於乙個顧客來講,如果當前的區間總份數小於他想要的份數,或者是區間最小 大於他能接受的最大 就把該顧客劃分到右區間,如若滿足則劃分到左區間。想要和 poi2011 met meteors一...