套路是人類進步的階梯,我將不惜一切代價套路學習!
—— 費清澄
恩恩真是太對了
zqc是乙隻套路的犰♂
zqc有乙個套路題庫,當然,他為了讓這個套路題庫不被發現,給題庫加了密。這個題庫有很多密碼,你只有輸入套路密碼後,你才能看到題目,並且題目的質量和套路密碼的長度成正比.根據你獲取到的情報,套路密碼為兩個字串的公共子串行,現在你想知道最長套路密碼的長度,以便獲得高質量的套路題目.
對於所有的資料滿足|s| ≤ 1e6 , |t| ≤ 1e3 , 字母均為小寫字母
顯然最長公共子串行有o(nm)的dp做法,但是顯然,這裡nm在1e9數量級,這個方法是行不通的.
車到山前必有路,有路必有老司機,這種題目,要麼是有比原來更加優秀的最長公共子串行求法,要麼就要利用題目本身的性質.
事實上,確實有這麼一種不同於原來o(nm)的dp的演算法,複雜度在o(nlogn)~o(nmlogn)之間.大致思路就是推廣了一下兩個串都是全排列時的情況,使其可以解決一般字串的問題.
設序列a長度為n,,序列b長度為m,,考慮a中所有元素在b中的序號,即a某元素在b的序號為,將這些序號按照降序排列,然後按照a中的順序得到乙個新序列,此新序列的最長嚴格遞增子串行即對應為a、b的最長公共子串行。
很明顯的可以看出,這個演算法的複雜度和原序列的字元稠密度有關,假如只有乙個字元,那麼複雜度就會退化到o(n²logn),但是如果全都不同,那就是o(nlogn)(此時就是全排列求lis).
那麼平均複雜度(假設每種字元出現頻率一樣)大概就是o(nm/p*logn),其中p是n和m中都出現過的字元個數.
#include #includeview code#include
#include
#include
#include
#include
#include
#include
using
namespace
std;
const
int maxn = 200000001
;vector
location[26
] ;int
c[maxn] , d[maxn] ;
char
a[maxn] , b[maxn] ;
inline
int get_max(int a,int b) //
nlogn 求lcs
int lcs(char a,char
b) d[
1] = c[0] ; d[0] = -1
;
for( i = ans = 1 ; i < k ; i++)
if( r == ans ) ans++,d[r+1] =c[i] ;
else
if( d[r+1] > c[i] ) d[r+1] =c[i] ;
}return
ans ;}
intmain()
}
如果不開subtask的話,可以通過大約70%的資料.
顯然這不是正解,因此我們需要換個思路.
那就需要考慮題目的特殊性質.我們可以看出,小的字串長度只有1e3,我們可以利用這個性質.顯然最長公共子串行的長度不會超過小的序列的長度,所以我們可以考慮進行如下的dp.
不妨令s表示長的序列,t表示短的序列,設dp[i][j]表示t的前i位和s的最長公共子串行的最後一位最小是多少,設對了狀態就很容易做了,下面給出**.
#include#includeview code#include
#include
#include
#include
#include
#include
#include
#include
#include
using
namespace
std;
const
int maxn=1000005
;int dp[1005][1005],weizhi[30][maxn],len1,len2,s1[maxn],s2[maxn],cnt[30
],ss[maxn];
char
a[maxn];
inline
intread()
while(ch>='
0'&&ch<='9'
)
return x*f;
}inline
void write(int
a)
else
}int
main()
for(int i=1;i<=len1;++i)
weizhi[s1[i]][++cnt[s1[i]]]=i;
if(weizhi[s2[1]][1
]) dp[
1][1]=weizhi[s2[1]][1
];
for(int i=1;i<=len2;++i)
dp[i][
0]=0
;
for(int i=1;ii)
for(int j=0;j<=i;++j)
}for(int i=len2;i>=1;--i)
if(dp[len2][i]<=1e9)
write(0);
return0;
}
複雜度為o(m²logn+n)
機房水題歡樂賽 2016 01 31
暨gdkoi校隊選拔賽 第1行為乙個正整數n 10000 表示有綠豆餅的卷數。第2行為n個正整數,表示這n卷綠豆餅的高度,兩個正整數之間會有乙個空格,高度值不會大於10000 輸出一行,包括乙個整數,表示修改之後最長的一段連續且高度嚴格上公升的綠豆餅的長度。行末以回車鍵結束。6 6 1 2 2 4 ...
機房水題歡樂賽 2016 04 24 下午
本次比賽為真 水題歡樂賽 給出乙個正整數n,把n分解成若干個不同的正整數相加,使得這若干個正整數的乘積最大.按公升序輸出這若干個正整數.3 420 的資料 n 20 40 的資料 n 200 60 的資料 n 1000 100 的資料 n 10000 盡量分到根號n處即可。這是乙個傳說中的猜數遊戲,...
網路賽水題
題目 一開始看確實很簡單的,但是暈死的題意距離坑了很多人。view code 1 typedef long long ll 2 const int n 1010 3 inta n 4int main 516 intflag 17for i 0 i n i 1831 sum 32 33if flag ...