bzoj2089&2090: [Poi2010]Monotonicity

  双倍经验一眼题。。。

  f[i][1/2]表示以i结尾,当前符号应该是</>的最长上升子序列, 用BIT优化转移就好

  =的话就不用说了吧= =

#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn=500010, inf=1e9+1;
int n, m, N, ans, ans1, ans2, ans3;
int tree[4][maxn], a[maxn], ty[maxn], mx[maxn], b[maxn];
char s[maxn];
void read(int &k)
{
    int f=1; k=0; char c=getchar();
    while(c<'0' || c>'9') c=='-' && (f=-1), c=getchar();
    while(c<='9' && c>='0') k=k*10+c-'0', c=getchar();
    k*=f;
}
inline int max(int a, int b){return a>b?a:b;}
inline void add(int x, int delta, int ty){for(;x<=N;x+=x&-x) tree[ty][x]=max(tree[ty][x], delta);}
inline int query(int x, int ty){int sum=0; for(;x;x-=x&-x) sum=max(tree[ty][x], sum); return sum;}
inline void update(int x, int delta)
{
    if(ty[(delta-1)%m+1]==1) add(N-a[x]+1, delta, 1);
    else if(ty[(delta-1)%m+1]==2) add(a[x], delta, 2);
    else mx[a[x]]=max(mx[a[x]], delta);
}
int main()
{
    read(n); read(m);
    for(int i=1;i<=n;i++) read(a[i]), b[i]=a[i]; N=n;
    sort(b+1, b+1+n); N=unique(b+1, b+1+n)-b-1;
    for(int i=1;i<=n;i++) a[i]=lower_bound(b+1, b+1+N, a[i])-b;
    for(int i=1;i<=m;i++)
    {
        scanf("%s", s+1);
        if(s[1]=='>') ty[(i-1)%m+1]=1;
        else if(s[1]=='<') ty[(i-1)%m+1]=2;
        else ty[(i-1)%m+1]=3;
    }
    for(int i=1;i<=n;i++)
    {
        int ans1=query(N-a[i], 1)+1, ans2=query(a[i]-1, 2)+1, ans3=mx[a[i]]+1;
        ans=max(ans, max(ans1, max(ans2, ans3))); 
        update(i, ans1); update(i, ans2); update(i, ans3);
    }
    printf("%d\n", ans);
}
View Code

 

转载于:https://www.cnblogs.com/Sakits/p/7919754.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值