多個串中,出現次數為k次的最長公共子串的個數,並且輸出。
一般的演算法就是字尾陣列加二分,複雜度o(n*logn)。其實也可以和poj3415一樣維護乙個棧,思想都是差不多的,維護乙個單調遞增的棧,每到乙個height[i]時,先保證棧單調遞增並且統計個數sum,然後height[i]再與當前最優值比較,如果大於最優值,那麼看sum是否大於k,如果大於則更新最優值。平均複雜度o(n)。
二分**:
1//status:c++_ac_375ms_4328kb
2 #include3 #include4 #include
5 #include6 #include7 #include
8 #include9 #include10 #include11 #include12 #include13
using
namespace
std;
14#define ll long long
15#define pii pair16
#define max(a,b) ((a)>(b)?(a):(b))
17#define min(a,b) ((a)<(b)?(a):(b))
18#define mem(a,b) memset(a,b,sizeof(a))
19#define lson l,mid,rt<<1
20#define rson mid+1,r,rt<<1|1
21#define pi acos(-1.0)
22const
int n=101010,inf=0x3f3f3f3f,mod=10000,sta=8000010;23
const ll lnf=0x3f3f3f3f3f3f3f3f;24
const
double dnf=1e13;
25//
26void swap(int& a,int& b)
27void swap(ll& a,ll& b)
28//
2930
intnum[n];
31int
sa[n],t1[n],t2[n],c[n],rank[n],height[n],vis[n],ma[n];
32int
n,m,t;
3334
void build_sa(int s,int n,int
m)3560}
6162
void getheight(int s,int
n)6372}
7374
int binary(int l,int
r)75
86else
88 k++;cnt=1
;89 vis[ma[sa[i]]]=k;90}
91}92 k++;
93if(cnt>t/2)ok=1;94
if(ok)ret=mid,l=mid+1;95
else r=mid-1;96
}97return
ret;98}
99100
intmain()
101114 ma[n]=i;
115 num[n++]=cnt++;
116}
117 num[n]=0
;118 m=cnt;
119 build_sa(num,n+1
,m);
120getheight(num,n);
121122 ans=binary(0,1001
);123
if(ans)
128 mem(vis,0
);129 k=1;cnt=1
;130 vis[ma[sa[1]]]=1
;131
for(i=2;i<=n;i++)
135else
141 k++;cnt=1
;142 vis[ma[sa[i]]]=k;
143}
144}
145if(cnt>t/2
)150
}151
else printf("
?\n"
);152 putchar('\n'
);153
}154
return0;
155 }
poj 3294 字尾陣列
題意 給定n個串,求最長的子串s,使得s為其中超過一半的串的公共子串。題解 字尾陣列,按height陣列分組,按sa陣列輸出。include include include using namespace std const int maxn 200000 int s maxn w maxn wa ...
poj3294 字尾陣列emmm
tle一下午,memset不能用太多,吧memset的陣列大小設定成正好,別設定太大 include include include include include include include include include include includeusing namespace std ...
POJ 3294 Life Forms(字尾陣列)
解題思路 求出所有 最長的 出現在超過一半所給字串的 子串。這題是在錯自閉了可以去poj discuss裡面,有本題資料的。反正我是瘋狂ole,re了一晚上。最後發現ole是 寫錯導致輸出的串的數量不對 其實也就是wa 所以導致debug的方向就出錯了。做法是二分答案,判斷是否可行,可行就記錄當前所...