CF650Dジップラインの問題解決

トピックポータル:CF650Dのジップライン

より良い読書体験

トピック効果は:配列と\(\) 繰り返し尋ねた(独立)とするように求め\(A_X \)となる(Y軸\)を\シーケンスの後\(LIS \)

まず、答えのみ+見出すことができる\(1 \) - \(1 \) 変更
元の配列の配列を使用してツリーを模索する\(LIS \) 設定(のf_i \)\に表される\(a_iを\)終わる\(LIS \)、\ (G_i \)で表さ\(a_iを\)で始まる\(LIS \)

\(1 \) + \(1 \)の場合:変更のみのため、\(a_iを\) 限りLISが私を通して見ると、
集合\(fは「\)を満たすために、\(J <Iをa_j <a_iを'\)最大\(F_J \)、\ (G' \)満足する\(J> I、a_j> a_iを\) 最大\(G_J \)の
場合(+ '+ G F' \ 1 > \)元の\(LIS \) 次いで\(ANS = '+ G F + 1 \')

\(2 \) - \(1 \)場合:まず\(Iは\)キーポイントでなければならない、すなわち、\(LIS \)が唯一の方法であり、次に何を判断する\( '+ G' + F 1 \)元未満である\(LIS \)は
:キー決定される
ため、\(のf_i + G [i]は = ANS \) そのドット表記の\(F_iと\)は +1オカレンス
IFF:キーポイントとき\(のf_i + g_i-1 =アンス\) と、そのような\(F_iと\)一度だけ表示されます

探している\(のf_i \)\(g_i \)言うためのプロセス言うまでもないが、フェンウィックツリー裸BEG \(LIS \)

探している\(Fを「\) オフラインは、xによって小規模から大規模まで、お願いします

探している\(G「\) 逆さまに再び掃引

#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;

#define rint register int
#define il inline
#define For(i,j,k) for(register int i=(j);i<=(k);++i)
#define Rep(i,j,k) for(register int i=(j);i>=(k);--i)

il int read(int x=0,int g=1,char ch='0')
{
    while(!isdigit(ch=getchar())) if(ch=='-') g=-1;
    while(isdigit(ch)) x=x*10+ch-'0',ch=getchar();
    return g*x;
}

const int N=8e5+5;
int a[N],b[N],g[N],f[N],c[N],cnt[N];
//g[i]:以第i个为开头,f[i]:以第i个为结尾的上升子序列长度
int n,m,ans,tmp,Ans[N];
struct node {int a,b,id,g,f;}q[N];
bool operator <(const node &n1,const node &n2) { return n1.a==n2.a?n1.b<n2.b:n1.a<n2.a; }

il void add(int x,int d) { for(;x<=tmp;x+=x&-x) c[x]=max(c[x],d); }
il int query(int x) { int ret=0; for(;x;x-=x&-x) ret=max(ret,c[x]); return ret; }
il void cls(int *c) { For(i,0,tmp) c[i]=0; }

il void work()
{
    sort(q+1,q+m+1);
    int t=1; cls(c); 
    For(i,1,m)
    {
        while(t<q[i].a) add(a[t],f[t]),++t;
        q[i].f=query(q[i].b-1);
    }
    
    t=n; cls(c);
    Rep(i,m,1)
    {
        while(t>q[i].a) add(tmp-a[t]+1,g[t]),--t;
        q[i].g=query(tmp-q[i].b);
        if(q[i].g+q[i].f+1>ans) Ans[q[i].id]=q[i].g+q[i].f+1;
    }

    For(i,1,m) if(!Ans[q[i].id])
    {
        if(f[q[i].a]+g[q[i].a]-1==ans&&cnt[f[q[i].a]]==1&&q[i].g+q[i].f+1<ans)
            Ans[q[i].id]=ans-1;
        else Ans[q[i].id]=ans;
    }
}

int main()
{   
    tmp=n=read(); m=read();
    For(i,1,n) b[i]=a[i]=read();
    For(i,1,m) q[i].a=read(),q[i].b=read(),q[i].id=i,b[++tmp]=q[i].b;
    sort(b+1,b+tmp+1); tmp=unique(b+1,b+tmp+1)-b-1;
    For(i,1,n) a[i]=lower_bound(b+1,b+tmp+1,a[i])-b;
    For(i,1,m) q[i].b=lower_bound(b+1,b+tmp+1,q[i].b)-b;//离散化
    ++tmp;
    For(i,1,n) f[i]=query(a[i]-1)+1,add(a[i],f[i]); cls(c);
    Rep(i,n,1) g[i]=query(tmp-a[i])+1,add(tmp-a[i]+1,g[i]);
    For(i,1,n) ans=max(ans,f[i]+g[i]-1);
    For(i,1,n) if(f[i]+g[i]-1==ans) ++cnt[f[i]];
    work();

    For(i,1,m) printf("%d\n",Ans[i]);
    return 0;
}

おすすめ

転載: www.cnblogs.com/wmq12138/p/11740738.html