水題歡樂賽 套路

2022-03-03 22:30:50 字數 2732 閱讀 4742

套路是人類進步的階梯,我將不惜一切代價套路學習!

—— 費清澄

恩恩真是太對了

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 #include 

#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()

}

view code

如果不開subtask的話,可以通過大約70%的資料.

顯然這不是正解,因此我們需要換個思路.

那就需要考慮題目的特殊性質.我們可以看出,小的字串長度只有1e3,我們可以利用這個性質.顯然最長公共子串行的長度不會超過小的序列的長度,所以我們可以考慮進行如下的dp.

不妨令s表示長的序列,t表示短的序列,設dp[i][j]表示t的前i位和s的最長公共子串行的最後一位最小是多少,設對了狀態就很容易做了,下面給出**.

#include#include

#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;

}

view code

複雜度為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 ...