hdu 6194 恰好出現k次的子串

2021-08-08 02:27:39 字數 3178 閱讀 5217

傳送門

題意:給你乙個字串,和乙個k,問你字串中恰好出現k次的子串有多少種。

思路:hdu4641的簡化版,hdu4641求的是》=k次的子串個數,所以現在我們只需跑兩次計算出》=k次的和》=k+1次的,兩者相減即位恰好出現k次的子串個數。

//china no.1

#pragma comment(linker, "/stack:1024000000,1024000000")

#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std;

#define pi acos(-1)

#define s_1(x) scanf("%d",&x)

#define s_2(x,y) scanf("%d%d",&x,&y)

#define s_3(x,y,z) scanf("%d%d%d",&x,&y,&z)

#define pi acos(-1)

#define endl '\n'

#define srand() srand(time(0));

#define me(x,y) memset(x,y,sizeof(x));

#define foreach(it,a) for(__typeof((a).begin()) it=(a).begin();it!=(a).end();it++)

#define close() ios::sync_with_stdio(0); cin.tie(0);

#define for(x,n,i) for(int i=x;i<=n;i++)

#define for(x,n,i) for(int i=x;i=x;i--)

#define for(n,x,i) for(int i=n;i>x;i--)

#define w while

#define sgn(x) ((x) < 0 ? -1 : (x) > 0)

#define bug printf("***********\n");

#define db double

#define ll long long

#define mp make_pair

#define pb push_back

typedef pairii;

typedef long long ll;

const int inf=0x3f3f3f3f;

const ll linf=0x3f3f3f3f3f3f3f3fll;

const int dx=;

const int dy=;

const int maxn=1e5+10;

const int maxx=600005;

const double eps=1e-8;

const double eps=1e-8;

const int mod=1e9+7;

templateinline t min(t a,t b,t c)

templateinline t max(t a,t b,t c)

templateinline t min(t a,t b,t c,t d)

templateinline t max(t a,t b,t c,t d)

template inline bool scan_d(t &ret)

while (c != '-' && (c < '0' || c > '9'))sgn = (c == '-') ? -1 : 1;ret = (c == '-') ? 0 : (c - '0');

while (c = getchar(), c >= '0' && c <= '9')ret *= sgn;return 1;}

inline bool scan_lf(double &num)else if(in=='.')

else num=in-'0';if(!isd)}

if(in!='.')else}

if(isn) num=-num;return true;}

void out(ll a)if(a >= 10) out(a / 10);putchar(a % 10 + '0');}

void print(ll a)

//freopen( "in.txt" , "r" , stdin );

//freopen( "data.txt" , "w" , stdout );

//cerr << "run time is " << clock() << endl;

int root,last;

int tots; //總結點

int l; //字串長度

struct sam_node

}t[maxn*2];

void sam_init()

void extend(int w)

if (p==-1) t[np].fa=root;

else

else}}

last=np;

}int w[maxn], r[maxn*2];

void topsort()

int dp[maxn*2];

char s[maxn];

int main()

for(int i = 0; i <= tots; ++i) dp[i] = 0;

topsort();

p = root;

for(int i = 0; i < l; ++i)

for(int i = tots; i >= 1; --i)

ll ans1 = 0, ans2 = 0;

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

if(dp[i] >= k)

ans1 += t[i].len-t[t[i].fa].len;

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

if(dp[i] >= k+1)

ans2 += t[i].len-t[t[i].fa].len;

printf("%lld\n", ans1-ans2);

}return 0;

}

hdu 6194 字尾陣列

題意 乙個字串,查詢恰好出現k次的子串的數目 思路 字尾陣列在height上進行操作。我們直接列舉長度為k的區間求min值,但是要注意的是直接這麼算是會重複的,同時也可能超過k次,這樣我們就需要把列舉的前乙個和後乙個都判斷一下,這樣保證了等於k次,同時也保證了沒有重複統計。includeusing ...

HDU6194 字尾陣列)

題意 告訴你乙個字串和k 求這個字串中有多少不同的子串恰好出現了k 次。解題思路 先用字尾陣列進行算出height,然後用st表維護,然後用區間長為k進行查詢,找出最小的height,目的是為了找出k都有的字串長度,然後區間往左右分別擴充套件乙個單位,目的是看看左右的重複情況,左右的最大值,代表超出...

HDU 6194 字尾陣列 RMQ

好絕望的。想了五個多小時,最後還是沒a。賽後看了下字尾陣列瞬間就有了思路。不過因為太菜,想了將近兩個小時才吧這個題乾掉。首先,應當認為,字尾陣列的定義是,某字串s的所有字尾按照字典序有小到大的順序排列 使用下標表示字尾 因為具體過程沒太看懂,但是參見劉汝佳藍書 演算法競賽黑暗聖典 可以得到乙個聰明的...