填坑 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),'\n');break;
            case 8:x=read();y=read();writ(getcha(x,y),'\n');break;
            case 9:x=read();y=read();z=read();writ(near(x,y,z),'\n');break;
            case 10:x=read();y=read();z=read();writ(rank(x,y,z),'\n');break;
            case 11:x=read();y=read();z=read();writ(sec(x,y,z),'\n');break;
        }
    }
    return 0;
}
View Code

 

posted @ 2018-10-16 07:07  _hcy_a  阅读(216)  评论(1编辑  收藏  举报