提交时间:2026-10-29 14:39:03

运行 ID: 43413

#include<bits/stdc++.h> using namespace std; #define int long long const int N = 3005; int n,k; char c[N]; int f[N][N]; long long cf[N]; signed main(){ cin >> n >> k; for(int i=1;i<=n;i++) cin >> c[i]; // 对角线双指针 O(n²) 求 f[x][y]:从x,y出发最多能延伸多长(汉明<=k) for(int d=1;d<n;d++){ // d = y - x int dis = 0, len = 0; for(int x=1, y=x+d; y <= n; x++, y++){ while(dis <= k && x+len <= n && y+len <= n){ dis += (c[x+len] != c[y+len]); len++; } f[x][y] = len - 1; dis -= (c[x] != c[y]); len--; } } memset(cf, 0, sizeof cf); for(int x=1;x<=n;x++){ for(int y=x+1;y<=n;y++){ int L = f[x][y]; int lim = min(L, y - x); // 等价于原版slv:for t in 0~lim-1: cf[x+t]++ cf[x] += 1; cf[x + lim] -= 1; } } // 一次前缀和,和原版最后一步一样 for(int i=1;i<=n;i++) cf[i] += cf[i-1]; for(int i=1;i<=n-1;i++) cout << cf[i] << '\n'; return 0; }