zoukankan      html  css  js  c++  java
  • Atcoder 077E

    题目链接:http://arc077.contest.atcoder.jp/tasks/arc077_c

    分析:如果某条线段包含x,显然应该先按一下到x,再从x走,反之必然是直接走过去,很容易想到用dp做,记len[i]为包含i点的线段长度之和,s[i]为以i为起点的线段数目,con[i]为包含i的线段数目,t[i]为以i为终点的线段数目,可以推出

    dp[i+1]=dp[i]+len[i]+s[i]-con[i+1]-t[i]+s[i+1],输入时将需要的数字预处理好,con用线段树区间修改下,总的复杂度为O(nlogm+m)。

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 using namespace std;
     5 typedef long long ll;
     6 const int maxn=1e5+5;
     7 int n,m;
     8 ll s[maxn],len[maxn],dp[maxn],t[maxn];
     9 class segTree{
    10     int a[maxn],s[maxn*4],lazy_tag[maxn*4];
    11 public:
    12     segTree(){
    13         memset(a,0,sizeof(a));
    14     }
    15     void build(int node,int begin,int end){
    16         lazy_tag[node]=0;
    17         if(begin==end){
    18             s[node]=a[begin];
    19         }else{
    20             build(2*node,begin,(begin+end)/2);
    21             build(2*node+1,(begin+end)/2+1,end);
    22             s[node]=s[2*node]+s[2*node+1];
    23         }
    24     }
    25     int query(int k){
    26         return a[k];
    27     }
    28     void PushDown(int node,int begin,int end){
    29         if(begin==end){
    30             s[node]+=lazy_tag[node];
    31             a[begin]=s[node];
    32         }else{
    33             lazy_tag[2*node]+=lazy_tag[node];
    34             lazy_tag[2*node+1]+=lazy_tag[node];
    35         }
    36         s[node]+=lazy_tag[node]*(end-begin+1);
    37         lazy_tag[node]=0;
    38     }
    39     void Change(int node,int begin,int end,int left,int right,int num){
    40         if(begin>=left&&end<=right){
    41             lazy_tag[node]+=num;
    42         }else{
    43             PushDown(node,begin,end);
    44             int m=(begin+end)/2;
    45             if(!(left>m||right<begin))
    46                 Change(2*node,begin,m,left,right,num);
    47             if(!(left>end||right<m+1))
    48                 Change(2*node+1,m+1,end,left,right,num);
    49         }
    50     }
    51     void PushDown_all(int node,int begin,int end){
    52         PushDown(node,begin,end);
    53         if(begin!=end){
    54             PushDown_all(2*node,begin,(begin+end)/2);
    55             PushDown_all(2*node+1,(begin+end)/2+1,end);
    56         }
    57     }
    58 }contain;
    59 int main(){
    60     //freopen("e:\in.txt","r",stdin);
    61     memset(s,0,sizeof(s));
    62     memset(t,0,sizeof(t));
    63     memset(dp,0,sizeof(dp));
    64     memset(len,0,sizeof(len));
    65     int a,b;
    66     scanf("%d%d",&n,&m);
    67     contain.build(1,1,m);
    68     scanf("%d",&a);
    69     for(int i=1;i<n;i++){
    70         s[a]++;
    71         scanf("%d",&b);
    72         t[b]++;
    73         len[b]+=(b-a+m)%m;
    74         if(b>a){
    75             contain.Change(1,1,m,a,b,1);
    76         }else{
    77             contain.Change(1,1,m,1,b,1);
    78             contain.Change(1,1,m,a,m,1);
    79         }
    80         dp[1]+=min((b-a+m)%m,1+(b-1+m)%m);
    81         a=b;
    82     }
    83     contain.PushDown_all(1,1,m);
    84     for(int i=1;i<m;i++){
    85         dp[i+1]=dp[i]+len[i]-t[i]+s[i]-contain.query(i+1)+s[i+1];
    86     }
    87     ll ans=dp[1];
    88     for(int i=2;i<=m;i++)
    89         ans=min(ans,dp[i]);
    90     printf("%lld
    ",ans);
    91     return 0;
    92 }
  • 相关阅读:
    二 、异常
    Java的基本概念
    Oracle case when
    oracle exists
    一 、前言
    location
    HTTP1.1初识
    数学学习笔记(持续更新中)
    [NOIP2017 提高组] 列队 题解
    [NOI2019] 回家路线 题解
  • 原文地址:https://www.cnblogs.com/7391-KID/p/7200544.html
Copyright © 2011-2022 走看看