codeforces 261D Maxim and Increasing Subsequence(树状数组优化最长上升子列)

题目链接:http://codeforces.com/problemset/problem/261/D

题意:最长上升子列。

思路:树状数组优化求最长上升子列。

#include <iostream>

#include <cstdio>

#include <string.h>

#include <algorithm>

#include <cmath>

#include <vector>

#include <queue>

#include <set>

#include <stack>

#include <string>

#include <map>



#define max(x,y) ((x)>(y)?(x):(y))

#define min(x,y) ((x)<(y)?(x):(y))

#define abs(x) ((x)>=0?(x):-(x))

#define i64 long long

#define u32 unsigned int

#define u64 unsigned long long

#define clr(x,y) memset(x,y,sizeof(x))

#define CLR(x) x.clear()

#define ph(x) push(x)

#define pb(x) push_back(x)

#define Len(x) x.length()

#define SZ(x) x.size()

#define PI acos(-1.0)

#define sqr(x) ((x)*(x))



#define FOR0(i,x) for(i=0;i<x;i++)

#define FOR1(i,x) for(i=1;i<=x;i++)

#define FOR(i,a,b) for(i=a;i<=b;i++)

#define DOW0(i,x) for(i=x;i>=0;i--)

#define DOW1(i,x) for(i=x;i>=1;i--)

#define DOW(i,a,b) for(i=a;i>=b;i--)

using namespace std;





int K,n,maxb,t;

int a[100005],c[100005],ans[100005];



void update(int x,int d)

{

    while(x<=maxb)

    {

        if(d>c[x]) c[x]=d;

        x+=x&-x;

    }

}



int get(int x)

{

    int ans=0;

    while(x>0)

    {

        ans=max(ans,c[x]);

        x-=x&-x;

    }

    return ans;

}



int cal()

{

    clr(c,0);

    clr(ans,0);

    int i,j,k;

    for(i=1;i<=t;i++) for(j=1;j<=n;j++)

    {

        k=get(a[j]-1)+1;

        if(k>ans[j])

        {

            ans[j]=k;

            update(a[j],k);

        }

    }

    return *max_element(ans+1,ans+n+1);

}



int main()

{

    scanf("%d%d%d%d",&K,&n,&maxb,&t);

    int i;

    while(K--)

    {

        for(i=1;i<=n;i++) scanf("%d",&a[i]);

        if(t>=maxb)

        {

            sort(a+1,a+n+1);

            printf("%d\n",unique(a+1,a+n+1)-(a+1));

            continue;

        }

        printf("%d\n",cal());

    }

    return 0;

}

  

你可能感兴趣的:(codeforces)