[USACO17FEB]Why Did the Cow Cross the Road II

[题目链接]

       https://www.lydsy.com/JudgeOnline/problem.php?id=4990

[算法]

        首先记录b中每个数的出现位置 , 记为P

        对于每个ai , 枚举(ai - 4) - (ai + 4) , 将Pj从大到小加入序列

        然后求最长上升子序列即可 , 详见代码

        时间复杂度 : O(NlogN)

[代码]

        

#include<bits/stdc++.h>
using namespace std;
#define MAXN 1000010

int n , len;
int a[MAXN] , pos[MAXN] , tmp[MAXN] , f[MAXN] , value[MAXN];

template <typename T> inline void chkmax(T &x,T y) { x = max(x , y); }
template <typename T> inline void chkmin(T &x,T y) { x = min(x , y); }
template <typename T> inline void read(T &x)
{
    T f = 1; x = 0;
    char c = getchar();
    for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
    for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - '0';
    x *= f;
}
struct BinaryIndexedTree
{
    int c[MAXN];
    inline int lowbit(int x)
    {
        return x & (-x);
    }
    inline int query(int x)
    {
        int ret = 0;
        for (int i = x; i; i -= lowbit(i)) chkmax(ret , c[i]);
        return ret;
    }
    inline void modify(int x , int val)
    {
        int ret = 0;
        for (int i = x; i <= n; i += lowbit(i)) chkmax(c[i] , val);
    }
} BIT;

int main()
{
    
    read(n);
    for (int i = 1; i <= n; i++) read(a[i]);
    for (int i = 1; i <= n; i++)
    {
        int x;
        read(x);
        pos[x] = i;    
    }    
    for (int i = 1; i <= n; i++)
    {
        int l = 0;
        for (int j = max(a[i] - 4 , 1); j <= min(a[i] + 4 , n); j++) tmp[++l] = pos[j];
        sort(tmp + 1,tmp + l + 1,greater<int>());
        for (int j = 1; j <= l; j++) value[++len] = tmp[j];
    }
    int ans = 0;
    for (int i = 1; i <= len; i++)
    {
        f[i] = BIT.query(value[i] - 1) + 1;
        BIT.modify(value[i] , f[i]);
        chkmax(ans , f[i]);
    }
    printf("%d\n",ans);
    
    return 0;
}

 

posted @ 2018-10-22 14:04  evenbao  阅读(178)  评论(0编辑  收藏  举报