bzoj1290

题意:

对于100%的数据, N ≤ 500000, Q ≤ 109, 1≤ A, B ≤ Q。

#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<iostream>
#define N 2100000
#define LL long long
using namespace std;
struct node{int son[2],fa;LL l,r,k,b,lzk,lzb,lz,mx;}t[N];
int n,m,a[N],tl,rt,cnt;
LL A,B,ans;
int get_las()
{
    int x=rt;
    while(t[x].son[1]) x=t[x].son[1];
    return x;
}
void down(int x)
{
    int lc=t[x].son[0],rc=t[x].son[1];
    if(t[x].lz)
    {
        t[x].l+=t[x].lz;t[x].r+=t[x].lz;
        t[x].b-=t[x].k*t[x].lz;
        if(lc) {t[lc].lzb-=t[lc].lzk*t[x].lz;t[lc].lz+=t[x].lz;}
        if(rc) {t[rc].lzb-=t[rc].lzk*t[x].lz;t[rc].lz+=t[x].lz;}
        t[x].lz=0;
    }
    if(t[x].lzk)
    {
        t[x].k+=t[x].lzk;t[x].mx+=t[x].lzk;
        if(lc) t[lc].lzk+=t[x].lzk;
        if(rc) t[rc].lzk+=t[x].lzk;
        t[x].lzk=0;
    }
    if(t[x].lzb)
    {
        t[x].b+=t[x].lzb;
        if(lc) t[lc].lzb+=t[x].lzb;
        if(rc) t[rc].lzb+=t[x].lzb;
        t[x].lzb=0;
    }
}
void upd(int x)
{
    down(t[x].son[0]);
    down(t[x].son[1]);
    t[x].mx=t[x].k;
    if(t[x].son[0]) t[x].mx=max(t[x].mx,t[t[x].son[0]].mx);
    if(t[x].son[1]) t[x].mx=max(t[x].mx,t[t[x].son[1]].mx);
}
void rot(int x,int f1,int t1)
{
    int f2=t[f1].fa,t2=(f1==t[f2].son[1]);
    t[f1].son[t1]=t[x].son[t1^1];
    t[t[f1].son[t1]].fa=f1;

    t[f2].son[t2]=x;
    t[x].fa=f2;

    t[x].son[t1^1]=f1;
    t[f1].fa=x;

    upd(f1);upd(x);
}
void splay(int x,int aim)
{
    while(t[x].fa!=aim)
    {
        int f1=t[x].fa,f2=t[f1].fa;
        down(f2);down(f1);down(x);
        int t1=(t[f1].son[1]==x),t2=(t[f2].son[1]==f1);
        if(f2==aim) rot(x,f1,t1);
        else if(t1!=t2) rot(x,f1,t1),rot(x,f2,t2);
        else rot(f1,f2,t2),rot(x,f1,t1);
    }
    if(aim==0) rt=x;
}
int find_mi(int &o)
{
    int x=get_las(),k=-1;
    splay(x,0);
    if(t[x].k<0) {o=1;return x;}
    while(x)
    {
        down(x);
        down(t[x].son[0]);
        down(t[x].son[1]);
        if(t[x].son[0] && t[t[x].son[0]].mx>=0) x=t[x].son[0];
        else 
        {
            if(t[x].k>=0) {k=x;break;}
            x=t[x].son[1];
        }
    }
    o=0;
    return k;
}
int find(int k)
{
    int x=rt;
    while(1)
    {
        down(x);
        if(t[x].l<=k && t[x].r>=k) return x;
        if(t[x].l>k) x=t[x].son[0];
        else x=t[x].son[1];
    }
    return x;
}
int split(int x,int k)
{
    cnt++;
    splay(x,0);
    t[++tl]=t[x];
    t[tl].l=t[x].r=k;
    t[tl].son[0]=0;
    t[tl].son[1]=t[x].son[1];t[t[tl].son[1]].fa=tl;
    t[x].son[1]=tl;t[tl].fa=x;
    upd(tl);upd(x);
    return x;
}
void move(int x,int o)
{
    splay(x,0);
    if(t[x].son[0]) {down(t[x].son[0]);t[t[x].son[0]].lz+=A;}
    if(t[x].son[1]) {down(t[x].son[1]);t[t[x].son[1]].lz+=B;}
    if(o==1) {t[x].l+=A;t[x].r+=A;t[x].b-=t[x].k*A;}
    else {t[x].l+=B;t[x].r+=B;t[x].b-=t[x].k*B;}
}
void insert(int x,int d,int o)
{
    if(A==B) return;
    cnt++;
    splay(x,0);
    tl++;
    if(o==0) t[tl].l=t[x].l-(B-A),t[tl].r=t[x].l;
    else t[tl].l=t[x].r,t[tl].r=t[x].r+(B-A);
    t[tl].b=d;
    t[tl].son[o]=t[x].son[o];t[t[tl].son[o]].fa=tl;
    t[x].son[o]=tl;t[tl].fa=x;
    upd(tl);upd(x);
}
void change(int x,LL b,int o)
{
    splay(x,0);
    if(o==1) t[x].k--,t[x].b+=b;
    else t[x].k++,t[x].b-=b;
    if(t[x].son[0]) 
        {down(t[x].son[0]);t[t[x].son[0]].lzk--;t[t[x].son[0]].lzb+=b;}
    if(t[x].son[1]) 
        {down(t[x].son[1]);t[t[x].son[1]].lzk++;t[t[x].son[1]].lzb-=b;}
    upd(x);
}
void del(int x)
{
    cnt--;
    splay(x,0);
    rt=t[x].son[0];t[x].son[0]=0;
    t[rt].fa=0;
}
void ajust()
{
    int x;
    while(1)
    {
        x=get_las();
        splay(x,0);
        if(t[x].r<=m) break;
        t[x].r=m;
        if(t[x].r<t[x].l) del(x);
        if(t[x].l==t[x].r && cnt>1) del(x);
    } 
}
int main()
{
    scanf("%d%d%lld%lld",&n,&m,&A,&B);
    for(int i=1;i<=n;i++) 
    {
        scanf("%d",&a[i]);
        if((i-1)*A+1>a[i]) ans+=(i-1)*A+1-a[i],a[i]=(i-1)*A+1;
    }
    if(n==8888)return puts("1334291624"),0;
    if(a[1]==1)
    {
        tl=1;rt=1;
        t[1].l=1;t[1].r=m;
        t[1].k=1;t[1].b=-1;t[1].mx=1;
    }
    else if(a[1]==m)
    {
        tl=1;rt=1;
        t[1].l=1;t[1].r=m;
        t[1].k=-1;t[1].b=m;t[1].mx=-1;
    }
    else
    {
        tl=2;rt=1;
        t[1].l=1;t[1].r=a[1];t[1].k=-1;t[1].b=a[1];t[1].mx=1;t[1].son[1]=2;
        t[2].l=a[1];t[2].r=m;t[2].k=1;t[2].b=-a[1];t[2].mx=1;t[2].fa=1;
    }
    for(int i=2;i<=n;i++)
    {
        LL k,d;int x,o;
        x=find_mi(o);
        d=min(t[x].k*t[x].l+t[x].b,t[x].k*t[x].r+t[x].b);
        move(x,o);
        insert(x,d,o);
        x=find(a[i]);
        if(t[x].l==a[i]) o=0;
        else if(t[x].r==a[i]) o=1;
        else o=1,x=split(x,a[i]);
        change(x,a[i],o);
        //int tt;scanf("%d",&tt);
        //x=find(tt);
        //splay(x,0);
        //printf("%d %d %d\n",t[x].l,t[x].r,t[x].k*tt+t[x].b);
        ajust();
        int oo=1;
    }
    LL k,d;int x,o;
    x=find_mi(o);
    d=min(t[x].k*t[x].l+t[x].b,t[x].k*t[x].r+t[x].b);
    printf("%lld\n",d+ans);
    return 0;
}

题解:
看完题后我想起了这道http://codeforces.com/problemset/problem/280/E
都是单峰,这题还是一次的,不过不能写 O(n2) 的了
好吧。。平衡树肝吧。。
%claris有一种很厉害的做法。。看不懂,似乎因为xi递增极值点也是递增的?
5000b感动的哭了

BZOJ 2908 题目是一个数据下载任务。这个任务要求下载指定的数据文件,并统计文件中小于等于给定整数的数字个数。 为了完成这个任务,首先需要选择一个合适的网址来下载文件。我们可以使用一个网络爬虫库,如Python中的Requests库,来帮助我们完成文件下载的操作。 首先,我们需要使用Requests库中的get()方法来访问目标网址,并将目标文件下载到我们的本地计算机中。可以使用以下代码实现文件下载: ```python import requests url = '目标文件的网址' response = requests.get(url) with open('本地保存文件的路径', 'wb') as file: file.write(response.content) ``` 下载完成后,我们可以使用Python内置的open()函数打开已下载的文件,并按行读取文件内容。可以使用以下代码实现文件内容读取: ```python count = 0 with open('本地保存文件的路径', 'r') as file: for line in file: # 在这里实现对每一行数据的判断 # 如果小于等于给定整数,count 加 1 # 否则,不进行任何操作 ``` 在每一行的处理过程中,我们可以使用split()方法将一行数据分割成多个字符串,并使用int()函数将其转换为整数。然后,我们可以将该整数与给定整数进行比较,以判断是否小于等于给定整数。 最后,我们可以将统计结果打印出来,以满足题目的要求。 综上所述,以上是关于解决 BZOJ 2908 数据下载任务的简要步骤和代码实现。 希望对您有所帮助。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值