BZOJ1109 [POI2007]堆积木Klo

    xiaoxiao2021-03-25  83

    随便推推,发现要求求a[i]-i单调不降,a[i]单调递增的最长子序列

    然后发现这两个条件可以推出i<j

    所以改变一下坐标然后求最长上升子序列即可

    注意双关键字排序

    注意吧a[i]-i>0的都continue了

    #include<iostream> #include<cstring> #include<ctime> #include<cmath> #include<algorithm> #include<iomanip> #include<cstdlib> #include<cstdio> #include<map> #include<bitset> #include<set> #include<stack> #include<vector> #include<queue> using namespace std; #define MAXN 100010 #define MAXM 1000010 #define ll long long #define eps 1e-8 #define MOD 1000000007 #define INF 1000000000 #define lb(x) x&-x struct data{ int x; int y; friend bool operator <(data x,data y){ return x.x!=y.x?x.x>y.x:x.y<y.y; } }; data a[MAXN]; int n; int c[MAXM]; int ans; void change(int x,int y){ for(;x<MAXM;x+=lb(x)){ c[x]=max(c[x],y); } } int ask(int x){ int re=0; for(;x;x-=lb(x)){ re=max(re,c[x]); } return re; } int main(){ int i,x; scanf("%d",&n); for(i=1;i<=n;i++){ scanf("%d",&x); a[i].x=x-i; a[i].y=x; } sort(a+1,a+n+1); for(i=1;i<=n;i++){ if(a[i].x>0){ continue ; } x=ask(a[i].y-1)+1; ans=max(ans,x); change(a[i].y,x); } printf("%d\n",ans); return 0; } /* */

    转载请注明原文地址: https://ju.6miu.com/read-19684.html

    最新回复(0)