最长公共子序列 线段树版的LCS

来源:互联网 发布:python 分布式 web 编辑:程序博客网 时间:2024/06/06 18:02
#include<iostream>#include<cstring>#include<algorithm>#include<vector>#define N 200008#define Musing namespace std;int hash1[N], hash2[N], x[N], y[N], dp[N], next1[N], next2[N];vector <int> v[N];struct LTree{    int a, b, big;}T[N];int e1(int a){    int i = a;    while (next1[i] != i)        i = e1(next1[i]);    return next1[a] = i;}int e2(int a){    int i = a;    while (next2[i] != i)        i = e2(next2[i]);    return next2[a] = i;}void f1(int a, int b){    int i = e1(b);    hash1[i] = a;    next1[i] = i + 1;    return;}void f2(int a, int b){    int i = e2(b);    hash2[i] = a;    next2[i] = i + 1;    return;}void build(int i){    T[i].big = 0;    if (T[i].a != T[i].b)    {        int t = i*2+1;        T[t].a = T[i].a;        T[t].b = (T[i].a+T[i].b)/2;        build(t);        t++;        T[t].a = (T[i].a+T[i].b)/2 + 1;        T[t].b = T[i].b;        build(t);    }}void insert(int i, int x, int k){    if (x < T[i].a || x > T[i].b)        return;    T[i].big = max(T[i].big, k);    if (T[i].a == T[i].b)        return;    if (x <= (T[i].a+T[i].b)/2)        insert(i*2+1, x, k);    else        insert(i*2+2, x, k);}int ask(int i, int x){    if (x < T[i].a)        return 0;    if (T[i].b <= x)        return T[i].big;    if (x <= (T[i].a+T[i].b)/2)        return ask(i*2+1, x);    else        return max(T[i*2+1].big, ask(i*2+2, x));}int main(){    int t, test, n, m;    int i, j;    int a, b, all, count, temp, ad, ans, big;    scanf("%d", &test);    for (t=1; t<=test; t++)    {        scanf("%d%d", &n, &m);        memset(hash1, 0, sizeof(hash1));        memset(hash2, 0, sizeof(hash2));        all = n*m;        for (i=0; i<N; i++)        {            next1[i] = i;            next2[i] = i;        }        for (i=0; i<all; i++)        {            scanf("%d%d", &a, &b);            f1(a, b);        }        for (i=0; i<all; i++)        {            scanf("%d%d", &a, &b);            f2(a, b);        }        for (i=0, count=1; i<N && count<=all; i++)            if (hash1[i])                x[count++] = hash1[i];        for (i=0, count=1; i<N && count<=all; i++)            if (hash2[i])                y[count++] = hash2[i];        for (i=1; i<=all; i++)            v[i].clear();        for (i=1; i<=all; i++)            v[y[i]].push_back(i);        T[0].a = 1;        T[0].b = all;        build(0);        ans = 0;        for (i=1; i<=all; i++)        {            temp = (int)v[x[i]].size();            for (j=temp-1; j>=0; j--)            {                ad = v[x[i]][j];                big = ask(0, ad-1) + 1;                insert(0, ad, big);                ans = max(ans, big);            }        }        printf("Case #%d: %d/n", t, ans);    }    return 0;}

0 0
原创粉丝点击