傳送門
題意:給你乙個字串,和乙個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的所有字尾按照字典序有小到大的順序排列 使用下標表示字尾 因為具體過程沒太看懂,但是參見劉汝佳藍書 演算法競賽黑暗聖典 可以得到乙個聰明的...