CodeForces 474E 满足变化范围条件的最长上升序列:线段树加速

 1 #include<stdio.h>
 2 #include<cmath>
 3 #include<string.h>
 4 #include<algorithm>
 5 #include<map>
 6 using namespace std;
 7 long long a[1000005],b[1000005],pre[100005],maxv[1000005],from[1000005];
 8 void Print(int i)
 9 {
10     if (pre[i]==0) return;
11     Print(pre[i]);
12     printf("%d ",pre[i]);
13 }
14 void update(int o,int l,int r,int p,int v,int i)
15 {
16     int mid=(l+r)/2;
17     if (l==r){
18         if (v>maxv[o]) {maxv[o]=v;
19         from[o]=i;}
20         return;
21     }
22     if (p<=mid) update(o*2,l,mid,p,v,i);
23     else update(o*2+1,mid+1,r,p,v,i);
24     if (maxv[o*2]>=maxv[o*2+1]) {maxv[o]=maxv[o*2]; from[o]=from[o*2]; }
25     else {maxv[o]=maxv[o*2+1]; from[o]=from[o*2+1];}
26 }
27 int query(int o,int l,int r,int ql,int qr)
28 {
29     int mid=(l+r)/2,temp=0;
30     if (ql<=l&&qr>=r) return maxv[o];
31     if (ql<=mid) temp=max(temp,query(o*2,l,mid,ql,qr));
32     if (mid<qr) temp=max(temp,query(o*2+1,mid+1,r,ql,qr));
33     return temp;
34 }
35 int queryl(int o,int l,int r,int ql,int qr)
36 {
37     int mid=(l+r)/2,t1=0,t2=0,t3=0,t4=0;
38     if (ql<=l&&qr>=r) return from[o];
39     if (ql<=mid) {t1=query(o*2,l,mid,ql,qr); t3=queryl(o*2,l,mid,ql,qr); }
40     if (mid<qr) {t2=query(o*2+1,mid+1,r,ql,qr); t4=queryl(o*2+1,mid+1,r,ql,qr);}
41     if (t1>t2) return t3;
42     return t4;
43 }
44 int main()
45 {
46     int n,d,i,cnt,t,t1,t2,tt1,tt2;
47     scanf("%d%d",&n,&d);
48     for (i=1;i<=n;i++) { scanf("%I64d",&a[i]); b[i]=a[i]; }
49     sort(a+1,a+n+1);
50     cnt=unique(a+1,a+n+1)-a-1;
51     memset(maxv,0,sizeof(maxv));
52     memset(pre,0,sizeof(pre));
53     memset(from,0,sizeof(from));
54     for (i=1;i<=n;i++)
55     {
56         t1=t2=0;
57         t1=upper_bound(a+1,a+cnt+1,b[i]-d)-a-1; tt1=t1;
58         t2=lower_bound(a+1,a+cnt+1,b[i]+d)-a; tt2=t2;
59         if (t1>0) t1=query(1,1,cnt,1,t1);
60         if (t2<=cnt) t2=query(1,1,cnt,t2,cnt);
61         t=lower_bound(a+1,a+cnt+1,b[i])-a;
62         if (t1>=t2||tt2>cnt) {
63             if (t1>0) pre[i]=queryl(1,1,cnt,1,tt1);
64             update(1,1,cnt,t,t1+1,i);
65         }
66         else {
67            pre[i]=queryl(1,1,cnt,tt2,cnt);
68             update(1,1,cnt,t,t2+1,i);
69         }
70         //printf("%d\n",pre[i]);
71     }
72     t=query(1,1,cnt,1,cnt);
73      printf("%d\n",t);
74      t=queryl(1,1,cnt,1,cnt);
75      Print(t);
76     printf("%d\n",t);
77 }

http://codeforces.com/contest/474/problem/E

转载于:https://www.cnblogs.com/xiao-xin/articles/4009654.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值