zoukankan      html  css  js  c++  java
  • 填坑 bzoj3337

    算是个板子题吧,就是不知道啥时候能写出来。

    #include<cstring>
    #include<iostream>
    #include<cctype>
    #include<cstdio>
    #include<algorithm>
    #include<queue>
    #include<cmath>
    #define writ(x,c) write(x),putchar(c);
    typedef long long ll;
    const int N=10000,MAX=1<<29;
    using namespace std;
    inline int read()
    {
        char c;int x=0;bool f=0;
        for(;!isdigit(c);c=getchar()) if(c=='-') f=1;
        for(;isdigit(c);c=getchar()) x=(x<<1)+(x<<3)+(c^48);
        return (f ? -x : x);
    }
    template <class _T>
    void write(_T x)
    {
        if(x<0) putchar('-'),x=-x;
        if(x>9) write(x/10);
        putchar(x%10+'0');
    }
    int n,m,size;
    struct node
    {
        int d[1003],s[1003],rev,add,same,size,next;
        ll sum;
    }a[N];
    queue<int> q;
    void Init()
    {
    }
    int new_node()
    {
        int temp=q.front();q.pop();
        return temp;
    }
    void clear(int x){a[x].rev=a[x].add=a[x].same=a[x].size=a[x].rev=0;}
    void erase(int x){q.push(x);clear(x);}
    void find(int &pos,int &now)
    {
        for(now=0;a[now].next!=-1&&pos>a[now].size;now=a[now].next)
            pos-=a[now].size;
    }
    void down(int now)
    {
        int tot=a[now].size; 
        if(a[now].rev)
        {
            a[now].rev=false;
            int tt=(tot>>1);
            for(int u=1;u<=tt;u++) swap(a[now].d[u],a[now].d[tot-u+1]);
        }
        if(a[now].same!=0)
        {
            for(int u=1;u<=tot;u++)
                a[now].d[u]=a[now].same;
            a[now].sum=a[now].same*tot,a[now].same=0;
        }
        if(a[now].add!=0)
        {
            for(int u=1;u<=tot;u++)
                a[now].d[u]+=a[now].add;
            a[now].sum=a[now].sum+a[now].add*tot,a[now].add=0;
        }
    }
    void update(int x)
    {
        a[x].sum=0;
        for(int u=1;u<=a[x].size;u++)
            a[x].sum+=a[x].d[u],a[x].s[u]=a[x].d[u];
        sort(a[x].s+1,a[x].s+a[x].size+1);
    }
    void spilt(int now,int pos)
    {
        down(now);
        int t=new_node();
        for(int u=pos;u<=a[now].size;u++)
            a[t].d[++a[t].size]=a[now].d[u];
        a[t].next=a[now].next,a[now].next=t,a[now].size=max(pos-1,0);
        update(t);update(now);
    }
    void Merge(int now)
    {
        int k=a[now].next;
        down(now);down(k);
        for(int u=1;u<=a[k].size;u++)
            a[now].d[++a[now].size]=a[k].d[u];
        a[now].next=a[k].next;erase(k);
        update(now);
    }
    void maintain(int now)
    {
        for(;now!=-1;now=a[now].next)
            if(a[now].next!=-1&&a[now].size+a[a[now].next].size<=size)
                Merge(now); 
    }
    void ins(int pos,int x)
    {
        int now;pos++;
        find(pos,now);spilt(now,pos);
        a[now].d[++a[now].size]=x,a[now].sum+=x;
        int lalal;
        for(lalal=1;lalal<a[now].size;lalal++)
            if(a[now].s[lalal]>x) break;
        for(int u=a[now].size;u>lalal;u--)
            a[now].s[u]=a[now].s[u-1];
        a[now].s[lalal]=x;
        maintain(now);
    }
    void del(int pos)
    {
        int now;
        find(pos,now);down(now);
        for(int u=pos+1;u<=a[now].size;u++)
            a[now].d[u-1]=a[now].d[u];
        a[now].size--;
        update(now);maintain(now);
    }
    void solve(int l,int r,int &lp,int &rp)
    {
        int pos=l;
        find(pos,lp);spilt(lp,pos);
        pos=r+1;
        find(pos,rp);spilt(rp,pos);
        pos=r;
        find(pos,rp);
    }
    int st[N];
    void rverse(int l,int r)
    {
        int lp,rp;
        solve(l,r,lp,rp);
        int now=lp,top=0;
        for(int u=a[lp].next;u!=a[rp].next;u=a[u].next)
            st[++top]=u,a[u].rev^=1;
        a[st[1]].next=a[rp].next;
        for(int u=top;u>1;u--)
            a[st[u]].next=st[u-1];
        a[lp].next=rp;
        maintain(lp);
    }
    void slip(int l,int r,int k)
    {
        int lp,mp,rp,np;
        solve(l,r-k,lp,mp),solve(r-k+1,r,mp,rp);
        np=a[lp].next,a[lp].next=a[mp].next,a[mp].next=a[rp].next,a[rp].next=np;
        maintain(lp); 
    }
    void add(int l,int r,int val)
    {
        int lp,rp;
        solve(l,r,lp,rp);
        for(int now=a[lp].next;now!=a[rp].next;now=a[now].next)
            a[now].add+=val,a[now].sum=a[now].sum+a[now].size*val;
        maintain(lp);
    }
    void same(int l,int r,int val)
    {
        int lp,rp;
        solve(l,r,lp,rp);
        for(int now=a[lp].next;now!=a[rp].next;now=a[now].next)
            a[now].add=0,a[now].same=val,a[now].sum=a[now].size*val;
        maintain(lp);
    }
    ll getsum(int l,int r)
    {
        int lp,rp;
        solve(l,r,lp,rp);
        ll ans=0;
        for(int now=a[lp].next;now!=a[rp].next;now=a[now].next)
            ans=ans+a[now].sum;
        maintain(lp);
        return ans;
    }
    int getcha(int l,int r)
    {
        int lp,rp;
        solve(l,r,lp,rp);
        int maxx=-MAX,minn=MAX;
        for(int now=a[lp].next;now!=a[rp].next;now=a[now].next)
            if(a[now].size!=0)
                if(a[now].same!=0)
                    minn=min(minn,a[now].same+a[now].add),
                    maxx=max(maxx,a[now].same+a[now].add);
                else
                    minn=min(minn,a[now].s[1]+a[now].add),
                    maxx=max(maxx,a[now].s[a[now].size]+a[now].add);
        maintain(lp);
        return maxx-minn;
    }
    int near(int l,int r,int val)
    {
        int lp,rp;
        solve(l,r,lp,rp);
        int ans=MAX;
        for(int now=a[lp].next;now!=a[rp].next;now=a[now].next)
        {
            if(a[now].same)
                ans=min(ans,abs(val-a[now].same-a[now].add));
            else
            {
                int id=lower_bound(a[now].s+1,a[now].s+a[now].size+1,val-a[now].add)-a[now].s;
                if(id!=a[now].size+1)
                    ans=min(ans,a[now].s[id]+a[now].add-val);
                if(id!=1)
                    id--,ans=min(ans,val-a[now].s[id]-a[now].add);
            }
        }
        maintain(lp);
        return ans;
    }
    int rank(int l,int r,int k)
    {
        int lp,rp;
        solve(l,r,lp,rp);
        int ll=0,rr=MAX;
        while(ll<rr)
        {
            int mid=(ll+rr)/2+1,sum=1;
            for(int now=a[lp].next;now!=a[rp].next;now=a[now].next)
            {
                if(a[now].same!=0)
                {
                    if(a[now].same+a[now].add<mid)
                        sum=sum+a[now].size;
                }
                else
                {
                    int id=upper_bound(a[now].s+1,a[now].s+a[now].size+1,mid-a[now].add-1)-a[now].s;  
                    sum=sum+max(0,id-1);
                }
            }
            if(k>=sum) ll=mid;
            else rr=mid-1;
        }
        maintain(lp);  
        return ll;
    }
    int sec(int l,int r,int val)
    {
        int lp,rp;
        solve(l,r,lp,rp);
        int ans=0;
        for(int now=a[lp].next;now!=a[rp].next;now=a[now].next)
        {
            if(a[now].same!=0)
            {
                if(a[now].same+a[now].add<val)
                    ans=ans+a[now].size;
            }
            else
            {
                int it=upper_bound(a[now].s+1,a[now].s+a[now].size+1,val-a[now].add-1)-a[now].s;
                ans=ans+it-1;
            }
        }
        maintain(lp);
        return ans;
    }
    int main()
    {
        n=read(),size=sqrt(n);
        for(int i=1;i<N;i++) q.push(i);a[0].next=-1;a[0].size=0;
        for(int u=1;u<=n;u++)
        {
            int x=read();ins(u-1,x); 
        }
        m=read();
        while(m--)
        {
            register int op,x,y,z;op=read();
            switch(op)
            {
                case 1:x=read();y=read();ins(x,y);break;
                case 2:x=read();del(x);break;
                case 3:x=read();y=read();rverse(x,y);break;
                case 4:x=read();y=read();z=read();slip(x,y,z);break;
                case 5:x=read();y=read();z=read();add(x,y,z);break;
                case 6:x=read();y=read();z=read();same(x,y,z);break;
                case 7:x=read();y=read();writ(getsum(x,y),'
    ');break;
                case 8:x=read();y=read();writ(getcha(x,y),'
    ');break;
                case 9:x=read();y=read();z=read();writ(near(x,y,z),'
    ');break;
                case 10:x=read();y=read();z=read();writ(rank(x,y,z),'
    ');break;
                case 11:x=read();y=read();z=read();writ(sec(x,y,z),'
    ');break;
            }
        }
        return 0;
    }
    View Code
  • 相关阅读:
    docker入门
    spring aop切面入门
    java 拉姆达 lamdba get
    Spring 3
    Spring 进阶二
    腾讯云 视频 点播 视频上传接口
    js 实时获取后台数据 Spring
    Spring 进阶一
    hibernate 第四天 重点查询的方式
    hibernate 第三天
  • 原文地址:https://www.cnblogs.com/mordor/p/9795799.html
Copyright © 2011-2022 走看看