| ||||||||||
| Online Judge | Problem Set | Authors | Online Contests | User | ||||||
|---|---|---|---|---|---|---|---|---|---|---|
| Web Board Home Page F.A.Qs Statistical Charts | Current Contest Past Contests Scheduled Contests Award Contest | |||||||||
后缀树写的,本地跑了好多随机接近100000长的数据秒出,为啥交上去就超时???我记得后缀树是O(n)的啊#include <iostream>
#include <cstdlib>
#include <map>
#include <cstring>
#include <fstream>
#include <vector>
#include <algorithm>
#include <stdio.h>
using namespace std;
const char AnyChar = '$';
int ans = 0;
int thres;
class node{
public:
map<char, node*> children;
node* parent;
node* suffix;
int start;
int end;
int pathLength;
int nodeDepth;
int minLeaf;
int maxLeaf;
int getNodeDepth();
void getMinmax();
//int number;
int number;//only leaf node
node(){
parent = NULL;
number = -1;
nodeDepth = -1;
children.clear();
minLeaf = -1;
maxLeaf = -1;
}
vector<int> getLeafNumber();
size_t getSize();
};
vector<int> node::getLeafNumber(){
vector<int> res;
if(number != -1){
//vector<int> res;
res.push_back(number);
return res;
}
for(map<char, node*>::iterator it = children.begin(); it != children.end(); it++){
vector<int> child_res = it->second->getLeafNumber();
for(int i = 0; i < child_res.size(); i++) res.push_back(child_res[i]);
}
return res;
}
void node::getMinmax(){
if(minLeaf != -1) return;
if(number != -1){
minLeaf = number;
maxLeaf = number;
return;
}
minLeaf = 2147483647, maxLeaf = -1;
for(map<char, node*>::iterator it = children.begin(); it != children.end(); it++){
it->second->getMinmax();
if(it->second->maxLeaf > maxLeaf) maxLeaf = it->second->maxLeaf;
if(it->second->minLeaf < minLeaf) minLeaf = it->second->minLeaf;
}
}
class scanResult{
public:
node* lastNode;
char direction;
int offset;
scanResult(node* n, char c, int o): direction(c), offset(o), lastNode(n){}
scanResult(){}
};
class suffixTree{
public:
node* root;
char *str;
int length;
int nodeNumber;
suffixTree(char *s, int l){
root = new node;
nodeNumber = 1;
length = l;
str = s;
root->parent = root;
root->start = 0;
root->end = 0;
root->suffix = root;
root->pathLength = 0;
root->nodeDepth = 0;
}
~suffixTree(){
delete root;
}
scanResult fastScan(node* startNode, int startOffset, int endOffset);
scanResult slowScan(node* startNode, int startOffset, int endOffset);
node* slowScan(node* startNode, string targetString, int startOffset, int endOffset);
void buildSuffixTree();
vector<int> search(string searchString);
size_t getSize();
};
scanResult suffixTree::fastScan(node* startNode, int startOffset, int endOffset){
int remain = endOffset - startOffset;
node* currentNode = startNode;
while(remain >= 0){
char pivotChar = str[endOffset - remain];
node* next = currentNode->children[pivotChar];
int thisSpan = next->end - next->start;
if(remain == 0){
return scanResult(currentNode, AnyChar, 0);
}
else if(thisSpan <= remain){
remain -= thisSpan;
currentNode = next;
continue;
}
else{
return scanResult(currentNode, pivotChar, remain);
}
}
}
scanResult suffixTree::slowScan(node* startNode, int startOffset, int endOffset){
//cout << 1 << endl;
int i = startOffset;
node* currentNode = startNode;
while(i < endOffset){
if(currentNode->children.find(str[i]) == currentNode->children.end()){
return scanResult(currentNode, AnyChar, 0);
}
node* next = currentNode->children[str[i]];
int thisLength = next->end - next->start;
int j = 0;
while(j < thisLength){
if(str[i + j] != str[next->start + j]){
return scanResult(currentNode, str[i], j);
}
j++;
}
i += thisLength;
currentNode = next;
}
}
node* suffixTree::slowScan(node* startNode, string targetString, int startOffset, int endOffset){
int i = startOffset;
node* currentNode = startNode;
while(i < endOffset){
if(currentNode->children.find(targetString[i]) == currentNode->children.end()){
return NULL;
}
node* next = currentNode->children[targetString[i]];
int thisLength = next->end - next->start;
int j = 0;
while(j < thisLength){
if(i + j == endOffset){
return next;
}
if(targetString[i + j] != str[next->start + j]){
return NULL;
}
j++;
}
i += thisLength;
currentNode = next;
}
return currentNode;
}
void suffixTree::buildSuffixTree(){
node* headi = root, *headiplus1 = NULL;
node* wholeString = new node;
nodeNumber ++;
wholeString->parent = root;
wholeString->number = 0;
wholeString->start = 0;
wholeString->end = length;
wholeString->pathLength = length;
root->children.insert(make_pair(str[0], wholeString));
//wholeString->nodeDepth = 1;
//cout << length << endl;*/
for(int i = 0; i < length - 1; i++){
//cout << i << endl;
node* pheadi = headi->parent;
node* spheadi = pheadi->suffix;
node* sheadi;
scanResult sR;
int startOffset = headi->start, endOffset = headi->end;
if(headi == root){
//cout << i << endl;
//sheadi = root;
sR = slowScan(root, i+1, length);
//cout << i << endl;
if(sR.offset == 0){//at a node
node* currentNode = sR.lastNode;
node* newNode = new node;
nodeNumber ++;
newNode->parent = currentNode;
newNode->number = i+1;
newNode->pathLength = length - i - 1;
//newNode->nodeDepth = currentNode->nodeDepth + 1;
newNode->start = currentNode->pathLength + i + 1;
newNode->end = length;
currentNode->children.insert(make_pair(str[newNode->start], newNode));
//cout << newNode->start << endl;
headiplus1 = currentNode;
}
else{
//cout << i << endl;
node* lastNode = sR.lastNode;
node* nextNode = lastNode->children[sR.direction];
node* middleNode = new node;
node* newNode = new node;
nodeNumber += 2;
middleNode->parent = lastNode;
//middleNode->nodeDepth = lastNode->nodeDepth + 1;
lastNode->children[sR.direction] = middleNode;
nextNode->parent = middleNode;
//nextNode->nodeDepth = middleNode->nodeDepth + 1;
newNode->parent = middleNode;
//newNode->nodeDepth = middleNode->nodeDepth + 1;
newNode->number = i+1;
char newDNextNode = str[nextNode->start + sR.offset];
middleNode->children[newDNextNode] = nextNode;
newNode->pathLength = length - i - 1;
middleNode->pathLength = lastNode->pathLength + sR.offset;
char newDNewNode = str[i + 1 + middleNode->pathLength];
middleNode->children[newDNewNode] = newNode;
newNode->start = middleNode->pathLength + i + 1;
newNode->end = length;
int separate = nextNode->start + sR.offset;
middleNode->start = nextNode->start;
middleNode->end = separate;
nextNode->start = separate;
headiplus1 = middleNode;
}
headi = headiplus1;
continue;
}
//cout << i << endl;
if(pheadi == root) startOffset ++;
sR = fastScan(spheadi, startOffset, endOffset);
if(sR.offset == 0){//a node
headi->suffix = sR.lastNode;
scanResult sR1 = slowScan(sR.lastNode, i+1+sR.lastNode->pathLength, length);
if(sR1.offset == 0){//headi+1 is a node
headiplus1 = sR1.lastNode;
node* iplus1 = new node;
nodeNumber ++;
iplus1->number = i+1;
iplus1->pathLength = length - i - 1;
iplus1->parent = headiplus1;
//iplus1->nodeDepth = headiplus1->nodeDepth + 1;
char direction = str[i+1+headiplus1->pathLength];
headiplus1->children[direction] = iplus1;
iplus1->start = i+1+headiplus1->pathLength;
iplus1->end = length;
}
else{
node* lastNode = sR1.lastNode;
node* nextNode = lastNode->children[sR1.direction];
node* middleNode = new node;
node* newNode = new node;
nodeNumber += 2;
middleNode->parent = lastNode;
//middleNode->nodeDepth = lastNode->nodeDepth + 1;
lastNode->children[sR1.direction] = middleNode;
nextNode->parent = middleNode;
//nextNode->nodeDepth = middleNode->nodeDepth + 1;
newNode->parent = middleNode;
//newNode->nodeDepth = middleNode->nodeDepth + 1;
newNode->number = i+1;
char newDNextNode = str[nextNode->start + sR1.offset];
middleNode->children[newDNextNode] = nextNode;
newNode->pathLength = length - i - 1;
middleNode->pathLength = lastNode->pathLength + sR1.offset;
char newDNewNode = str[i + 1 + middleNode->pathLength];
middleNode->children[newDNewNode] = newNode;
newNode->start = middleNode->pathLength + i + 1;
newNode->end = length;
int separate = nextNode->start + sR1.offset;
middleNode->start = nextNode->start;
middleNode->end = separate;
nextNode->start = separate;
headiplus1 = middleNode;
}
}
else{
node* lastNode = sR.lastNode;
node* nextNode = lastNode->children[sR.direction];
node* middleNode = new node;
node* newNode = new node;
nodeNumber += 2;
middleNode->parent = lastNode;
lastNode->children[sR.direction] = middleNode;
nextNode->parent = middleNode;
newNode->parent = middleNode;
newNode->number = i+1;
char newDNextNode = str[nextNode->start + sR.offset];
middleNode->children[newDNextNode] = nextNode;
newNode->pathLength = length - i - 1;
middleNode->pathLength = lastNode->pathLength + sR.offset;
char newDNewNode = str[i + 1 + middleNode->pathLength];
middleNode->children[newDNewNode] = newNode;
newNode->start = middleNode->pathLength + i + 1;
newNode->end = length;
int separate = nextNode->start + sR.offset;
middleNode->start = nextNode->start;
middleNode->end = separate;
nextNode->start = separate;
headiplus1 = middleNode;
headi->suffix = middleNode;
}
headi = headiplus1;
//cout << i << endl;
}
}
void getAns(node *n){
//cout << n->number << " " << n->pathLength << " " << n->minLeaf << " " << n->maxLeaf << thres << endl;
if(n->minLeaf >= thres || n->maxLeaf <= thres) return;
int thisAns = n->pathLength;
if(thisAns > ans) ans = thisAns;
for(map<char, node*>::iterator it = n->children.begin(); it != n->children.end(); it++){
getAns(it->second);
}
}
void debug(node *n){
cout << n->number << " " << n->pathLength << " " << n->minLeaf << " " << n->maxLeaf << endl;
for(map<char, node*>::iterator it = n->children.begin(); it != n->children.end(); it++){
debug(it->second);
}
}
char c[200010] = {'\0'};
int main(int argc, char **argv){
int cnt;
scanf("%s",c);
thres = strlen(c);
c[thres] = '#';
scanf("%s", c+thres+1);
cnt = strlen(c);
c[cnt] = '$';
cnt ++;
suffixTree st(c, cnt);
st.buildSuffixTree();
st.root->getMinmax();
getAns(st.root);
//debug(st.root);
cout << ans << endl;
return 0;
}
Followed by:
Post your reply here: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator