zoukankan      html  css  js  c++  java
  • codeforces 278Div1 B题

    虚拟参赛的时候没想到是线段树,看到很多人都过了,也蛮着急的。

    首先用二分+线段树的方法更新DP[i]:它表示以A[i]为结尾可以最前到哪个位置;

    再用线段树计算ans[i]:它表示当前i个A元素可以最少分成多少个pieces,ans[i]=1+min(ans[j]),dp[i]-1<=j<=i-L。

    over.

    16 #define N 100000+5
     17 
     18 int a[N],dp[N],Ans[N];
     19 struct segment {
     20     int l,r;
     21     int Min,Max,ans;
     22 } seg[4*N];
     23 
     24 struct diff {
     25     int Max,Min;
     26     diff(int x=0,int n=0):Max(x),Min(n) {}
     27 };
     28 
     29 void build(int p,int l,int r)
     30 {
     31     seg[p].l=l, seg[p].r=r, seg[p].ans=-1;;
     32     if (l==r) {
     33         seg[p].Min = seg[p].Max = a[l];
     34         return;
     35     }
     36     build(p<<1,l,(l+r)>>1);
     37     build((p<<1)+1,((l+r)>>1)+1,r);
     38 
     39     seg[p].Min = min(seg[p<<1].Min, seg[(p<<1)+1].Min),
     40     seg[p].Max = max(seg[p<<1].Max, seg[(p<<1)+1].Max);
     41 }
     42 
     43 diff query1(int p,int l,int r)
     44 {
     45     if (l<=seg[p].l && seg[p].r<=r) {
     46         return diff(seg[p].Max,seg[p].Min);
     47     }
     48 
     49     diff t1,t2;
     50     bool f1=false, f2=false;
     51     if (seg[p<<1].r>=l)
     52         f1=true, t1=query1(p<<1,l,r);
     53     if (seg[(p<<1)+1].l<=r)
     54         f2=true, t2=query1((p<<1)+1,l,r);
     55 
     56     if (f1) {
     57         if (f2)
     58             return diff(max(t1.Max,t2.Max), min(t1.Min,t2.Min));
     59         else
     60             return t1;
     61     }
     62     else
     63         if (f2)
     64             return t2;
     65     return diff(0,0);
     66 }
     67 
     68 int query2(int p,int l,int r)
     69 {
     70     if (l<=seg[p].l && seg[p].r<=r) {
     71         return seg[p].ans;
     72     }
     73 
     74     int t1=-1,t2=-1;
     75     if (seg[p<<1].r>=l)
     76         t1=query2(p<<1,l,r);
     77     if (seg[(p<<1)+1].l<=r)
     78         t2=query2((p<<1)+1,l,r);
     79 
     80     if (t1==-1) {
     81         return t2;
     82     }
     83     else {
     84         if (t2==-1)
     85             return t1;
     86         else return min(t1,t2);
     87     }
     88 
     89 }
     90 
     91 void add(int p,int i,int newans)
     92 {
     93     if (seg[p].l==seg[p].r) {
     94         seg[p].ans=newans;
     95         return;
     96     }
     97 
     98     if (i<=seg[p<<1].r)
     99         add(p<<1,i,newans);
    100     else
    101         add((p<<1)+1,i,newans);
    102 
    103     if (seg[p<<1].ans==-1) {
    104         seg[p].ans = seg[(p<<1)+1].ans;
    105     }
    106     else {
    107         if (seg[(p<<1)+1].ans==-1)
    108             seg[p].ans=seg[p<<1].ans;
    109         else
    110             seg[p].ans=min(seg[p<<1].ans,seg[(p<<1)+1].ans);
    111     }
    112 }
    113 
    114 int main()
    115 {
    116     //freopen("b.txt","r",stdin);
    117 
    118     int n,s,l;
    119     cin>>n>>s>>l;
    120     for (int i=1;i<=n;i++) scanf("%d",&a[i]);
    121     build(1,1,n);
    122     for (int i=1;i<=n;i++) {
    123         int L=1,R=i-1;
    124         dp[i]=i;
    125         while (L<=R) {
    126             int mid = (L+R)>>1;
    127             diff tmp = query1(1,mid,i);
    128             if (tmp.Max-tmp.Min<=s) {
    129                 R=mid-1;
    130                 dp[i]=mid;
    131             }
    132             else {
    133                 L=mid+1;
    134             }
    135         }
    136     }
    137 
    138 
    139     for (int i=1;i<=n;i++) {
    140         if (i<l) {
    141             Ans[i]=-1;
    142             continue;
    143         }
    144         int tmp=-1;
    145         if (i-l>0 && dp[i]-1<=i-l)
    146             tmp=query2(1,max(1,dp[i]-1),i-l);
    147         if (dp[i]==1) tmp=0;
    148 
    149         if (tmp==-1)
    150             Ans[i]=-1;
    151         else
    152             Ans[i]=tmp+1, add(1,i,Ans[i]);
    153     }
    154     cout<<Ans[n]<<endl;
    155 
    156     return 0;
    157 }
  • 相关阅读:
    蛙蛙推荐:蛙蛙教你配置linux+mysql+.net环境
    今日阅读20081231学习remoting
    翻译:改进.NET应用程序的性能和可伸缩性(一)概述及ADO.NET 性能
    翻译:改进.NET应用程序的性能和可伸缩性(二)为性能和可伸缩性做架构和设计上的Review
    蛙蛙推荐:作一个支持过载自适应和动态扩容的负载均衡服务
    翻译:改进.NET应用程序的性能和可伸缩性(三)Remoting性能
    清空日志后备份数据库
    CLR宿主相关
    每日阅读20081216
    iis 无法安装提示错误,无法复制一个或多个文件,错误码0x4b8 dodo
  • 原文地址:https://www.cnblogs.com/nuaalida/p/4129407.html
Copyright © 2011-2022 走看看