codeforces819B Mister B and PR Shifts -- 线段树

来源:互联网 发布:淘宝网商银行存钱吗 编辑:程序博客网 时间:2024/06/18 09:16

di表示i次操作后的答案。
考虑pidj的贡献
ipi时:

  • dj+=pii+j , j[0,pii]
  • dj+=ipi+j , j[pii+1,ni]
  • dj+=pii+nj , j[ni+1,n1]

pi<i

  • dj+=ipi+j , j[0,ni]
  • dj+=pii+nj , j[ni+1,n+pii]
  • dj+=ipin+j , j[ni+pi+1,n1]

di=ki+b,枚举p,更新kb就可以了。
时间复杂度O(nlogn)加了读优才过

代码:

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;inline char nc(){    static char buf[100000],*p1=buf,*p2=buf;    if(p1==p2){        p2=(p1=buf)+fread(buf,1,100000,stdin);        if(p1==p2)return EOF;    }    return *p1++;}inline void Read(int& x){    char c=nc();    for(;c<'0'||c>'9';c=nc());    for(x=0;c>='0'&&c<='9';x=(x<<3)+(x<<1)+c-48,c=nc());}#define N 1000010#define ll long longll c[2][N<<2],p[2][N<<2],Tmp,Ans=1e18,d[N];int i,j,k,n,m,x;inline void Push(int x,int l){    int l1=l+1>>1,l2=l>>1;    if(p[0][x]){        if(l1==1)        c[0][x<<1]+=p[0][x];        p[0][x<<1]+=p[0][x];        if(l2==1)        c[0][x<<1|1]+=p[0][x];        p[0][x<<1|1]+=p[0][x];        p[0][x]=0;    }    if(p[1][x]){        if(l1==1)        c[1][x<<1]+=p[1][x];        p[1][x<<1]+=p[1][x];        if(l2==1)        c[1][x<<1|1]+=p[1][x];        p[1][x<<1|1]+=p[1][x];        p[1][x]=0;    }}inline void Update(int x,int l,int r,int L,int R,int y,bool d){    if(l>R||r<L)return;    if(l>=L&&r<=R){        if(l==r)c[d][x]+=y;        p[d][x]+=y;        return;    }    int Mid=l+r>>1;    Update(x<<1,l,Mid,L,R,y,d);    Update(x<<1|1,Mid+1,r,L,R,y,d);}inline void GetAns(int x,int l,int r){    if(l==r){        d[l]=c[0][x]+1ll*l*c[1][x];        return;    }    Push(x,r-l+1);    int Mid=l+r>>1;    GetAns(x<<1,l,Mid);    GetAns(x<<1|1,Mid+1,r);}inline void Add(int l,int r,int x,int y){    if(l>r)return;    Update(1,0,n-1,l,r,x,0);    Update(1,0,n-1,l,r,y,1);}int main(){    Read(n);    for(i=1;i<=n;i++){        Read(x);        if(x>=i)Add(0,x-i,x-i,-1),Add(x-i+1,n-i,i-x,1),Add(n-i+1,n-1,x-i+n,-1);else        Add(0,n-i,i-x,1),Add(n-i+1,n-i+x,x-i+n,-1),Add(n-i+x+1,n-1,i-x-n,1);    }    GetAns(1,0,n-1);    for(i=0;i<n;i++)if(d[i]<Ans)Ans=d[i],x=i;    printf("%I64d %d\n",Ans,x);    return 0;}
阅读全文
0 0