码迷,mamicode.com
首页 > 其他好文 > 详细

CodeForces 675E Trains and Statistic

时间:2016-09-14 15:12:27      阅读:170      评论:0      收藏:0      [点我收藏+]

标签:

贪心,递推,线段树,$RMQ$。

 

$RMQ$:

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<iostream>
using namespace std;
typedef long long LL;
const double pi=acos(-1.0),eps=1e-6;
void File()
{
    freopen("D:\\in.txt","r",stdin);
    freopen("D:\\out.txt","w",stdout);
}
template <class T>
inline void read(T &x)
{
    char c=getchar(); x=0;
    while(!isdigit(c)) c=getchar();
    while(isdigit(c)) {x=x*10+c-0; c=getchar();}
}

const int maxn=100010;
int a[maxn],n,tmp,dp[maxn][30];
LL ans[maxn];

void RMQ_init()
{
    for(int i=0;i<n;i++) dp[i][0]=i;
    for(int j=1;(1<<j)<=n;j++)
        for(int i=0;i+(1<<j)-1<n;i++){
            if(a[dp[i][j-1]]>a[dp[i+(1<<(j-1))][j-1]]) dp[i][j]=dp[i][j-1];
            else dp[i][j]=dp[i+(1<<(j-1))][j-1];
        }
}

int RMQ(int L,int R)
{
    int k=0;
    while((1<<(k+1))<=R-L+1) k++;
    if(a[dp[L][k]]>a[dp[R-(1<<k)+1][k]]) return dp[L][k];
    return dp[R-(1<<k)+1][k];
}

int main()
{
    scanf("%d",&n);
    for(int i=0;i<n-1;i++) scanf("%d",&a[i]),a[i]--;
    a[n-1]=n-1; RMQ_init(); ans[n-1]=0; LL d=0;
    for(int i=n-2;i>=0;i--)
    {
        tmp=RMQ(i+1,a[i]);
        ans[i]=ans[tmp]-(a[i]-tmp)+n-1-a[i]+a[i]-i;
        d=d+ans[i];
    }
    printf("%lld\n",d);
    return 0;
}

线段树:

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<iostream>
using namespace std;
typedef long long LL;
const double pi=acos(-1.0),eps=1e-6;
void File()
{
    freopen("D:\\in.txt","r",stdin);
    freopen("D:\\out.txt","w",stdout);
}
template <class T>
inline void read(T &x)
{
    char c=getchar(); x=0;
    while(!isdigit(c)) c=getchar();
    while(isdigit(c)) {x=x*10+c-0; c=getchar();}
}

const int maxn=100010;
int a[maxn],n,s[4*maxn],M,tmp;
LL ans[maxn];

void build(int l,int r,int rt)
{
    if(l==r) { s[rt]=a[l]; return; }
    int m=(l+r)/2; build(l,m,2*rt); build(m+1,r,2*rt+1);
    s[rt]=max(s[2*rt],s[2*rt+1]);
}

void f(int L,int R,int l,int r,int rt)
{
    if(L<=l&&r<=R) { M=max(M,s[rt]); return; }
    int m=(l+r)/2;
    if(L<=m) f(L,R,l,m,2*rt);
    if(R>m) f(L,R,m+1,r,2*rt+1);
}

void force(int l,int r,int rt)
{
    if(l==r) {tmp=l; return;}
    int m=(l+r)/2;
    if(s[2*rt]==M) force(l,m,2*rt);
    else force(m+1,r,2*rt+1);
}

void h(int L,int R,int l,int r,int rt)
{
    if(L<=l&&r<=R)
    {
        if(s[rt]<M) return;
        force(l,r,rt); return;
    }
    int m=(l+r)/2;
    if(L<=m) h(L,R,l,m,2*rt); if(tmp!=-1) return;
    if(R>m) h(L,R,m+1,r,2*rt+1); if(tmp!=-1) return;
}

int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n-1;i++) scanf("%d",&a[i]); a[n]=n;
    build(1,n,1); ans[n]=0; LL d=0;
    for(int i=n-1;i>=1;i--)
    {
        M=tmp=-1; f(i+1,a[i],1,n,1); h(i+1,a[i],1,n,1);
        ans[i]=ans[tmp]-(a[i]-tmp)+n-a[i]+a[i]-i;
        d=d+ans[i];
    }
    printf("%lld\n",d);
    return 0;
}

 

CodeForces 675E Trains and Statistic

标签:

原文地址:http://www.cnblogs.com/zufezzt/p/5872303.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!