zoukankan      html  css  js  c++  java
  • [3.30校内训练赛]

    来自FallDream的博客,未经允许,请勿转载,谢谢。

    ---------------------------------------------------

    ditoly这次打好了虐爆我们的主意,掏出三道丧题,囊括三种赛制,第一道丧病oi题,第二道sb交互题,第三道奇怪提答............

    第二道交互题没人做,也挺奇怪的,不讲了;

    第三道是找规律,也就50个数列把,我拿出我最强的找规律水平,用上插值啊快速幂啊矩阵乘法啊肉眼观察法啊乱差分啊等等办法,骗到了48分,貌似全场最高了..得分靠随缘,也不讲了。

    讲讲第一题,给定一个数列,需要支持100种操作。    $n,mleqslant 100000$

    1:查询一段区间,你每次可以任选其中一段区间+1或者-1,求把它变成全是0的最小次数。

    10:区间加一个值。  11:区间翻转   100:回到k次操作之前的状态。  

    看到这题,很明显可以可持久化平衡树,但我姿势不够,不会,而且丧病出题人卡空间。还好脑补了一种乱建边的方法,从一个状态向它能转移到的状态连边,然后dfs,离开时撤销,类似线段树分治。

    然后维护一棵平衡树,修改操作容易维护,查询操作的答案是这个区间差分的绝对值之和加上左右端点的绝对值之和除以2.  我把查询做成了只能-1,爆0了qaq

    #include<iostream>
    #include<cstdio>
    #define MN 100000
    #define ll long long
    using namespace std;
    inline int read()
    {
        int x = 0 , f = 1; char ch = getchar();
        while(ch < '0' || ch > '9'){ if(ch == '-') f = -1;  ch = getchar();}
        while(ch >= '0' && ch <= '9'){x = x * 10 + ch - '0';ch = getchar();}
        return x * f;
    }
    
    int s[MN+5],n,m,cnt=0;
    struct ques{int kind,l,r,x;ll ans;}q[MN+5];
    struct edge{int to,next;}e[MN+5];
    int fa[MN+5],c[MN+5][2],rt,head[MN+5],size[MN+5];
    ll num[MN+5],ad[MN+5],nl[MN+5],nr[MN+5],sum[MN+5];
    bool rev[MN+5];
    
    template<typename t> t abs(t x){return x<0?-x:x;}
    inline void ins(int f,int t){e[++cnt]=(edge){t,head[f]};head[f]=cnt;}
    
    void update(int x)
    {
        int l=c[x][0],r=c[x][1];
        nl[x]=(l?nl[l]:num[x]);nr[x]=(r?nr[r]:num[x]);
        size[x]=size[l]+size[r]+1;
        sum[x]=0;
        if(l) sum[x]+=sum[l]+abs(num[x]-nr[l]);
        if(r) sum[x]+=sum[r]+abs(num[x]-nl[r]);
    }
    
    inline void mark(int x,int z)
    {
        nl[x]+=z;nr[x]+=z;
        num[x]+=z;ad[x]+=z;
    }
    
    void pushdown(int x)
    {
        int l=c[x][0],r=c[x][1];
        if(rev[x]) 
        {
            rev[l]^=1;rev[r]^=1;rev[x]^=1;
            swap(c[l][0],c[l][1]);swap(c[r][0],c[r][1]);
            swap(nl[l],nr[l]);swap(nl[r],nr[r]);
        }
        if(ad[x])
        {
            mark(l,ad[x]);mark(r,ad[x]);
            ad[x]=0;
        }
    }
    
    void build(int&x,int l,int r,int last)
    {
        if(l>r) return;
        x=l+r>>1;fa[x]=last;num[x]=s[x];
        if(l==r) 
        {
            size[x]=1;nl[x]=nr[x]=s[x];sum[x]=0;
            return;
        }
        build(c[x][0],l,x-1,x);
        build(c[x][1],x+1,r,x);
        update(x);
    }
    
    void rotate(int x,int&k)
    {
        int y=fa[x],z=fa[y],l=c[y][1]==x,r=l^1;
        if(y==k) k=x; else c[z][c[z][1]==y]=x;
        fa[x]=z;fa[y]=x;fa[c[x][r]]=y;
        c[y][l]=c[x][r];c[x][r]=y;
        update(y);update(x);
    }
    
    void splay(int x,int&k)
    {
        while(x!=k)
        {
            int y=fa[x],z=fa[y];
            if(y!=k)
            {
                if(c[z][1]==y^c[y][1]==x) rotate(x,k);
                else rotate(y,k);    
            } 
            rotate(x,k);
        }
    }
    
    int find(int x,int rk)
    {
        pushdown(x);
        int sz=size[c[x][0]]+1;
        if(sz==rk) return x;
        else if(sz<rk) return find(c[x][1],rk-sz);
        else return find(c[x][0],rk);
    }
    
    int split(int l,int r)
    {
        splay(find(rt,l),rt);splay(find(rt,r),c[rt][1]);
        return c[c[rt][1]][0];
    }
    
    void solve(int x)
    {
        if(q[x].kind==1) 
        {
            ll y=sum[split(q[x].l,q[x].r+2)];
            q[x].ans=(1LL*abs(num[find(rt,q[x].l+1)])+abs(num[find(rt,q[x].r+1)])+y)/2;
        }
        if(q[x].kind==10)
        {
            int y=split(q[x].l,q[x].r+2);mark(y,q[x].x); 
            update(c[rt][1]);update(rt);
        }
        if(q[x].kind==11) 
        {
            int y=split(q[x].l,q[x].r+2);
            rev[y]^=1;swap(c[y][0],c[y][1]);
            swap(nl[y],nr[y]);
            update(c[rt][1]);update(rt);
        }
        for(int i=head[x];i;i=e[i].next)
            solve(e[i].to);
        if(q[x].kind==10)
        {
            int y=split(q[x].l,q[x].r+2);
            mark(y,-q[x].x); 
            update(c[rt][1]);update(rt);
        }
        if(q[x].kind==11)
        {
            int y=split(q[x].l,q[x].r+2);
            rev[y]^=1;swap(c[y][0],c[y][1]);
            swap(nl[y],nr[y]);
            update(c[rt][1]);update(rt);
        }
    }
    
    int main()
    {
        n=read();m=read();
        for(int i=1;i<=n;i++)s[i+1]=read();
        for(int i=1;i<=m;i++)
        {
            q[i].kind=read();
            if(q[i].kind==1) q[i].l=read(),q[i].r=read();
            if(q[i].kind==10) q[i].l=read(),q[i].r=read(),q[i].x=read();
            if(q[i].kind==11) q[i].l=read(),q[i].r=read();
            if(q[i].kind==100) q[i].x=read(),ins(i-q[i].x-1,i);
            else ins(i-1,i);
        }
        cnt=0;build(rt,1,n+2,0);
        solve(0);
        for(int i=1;i<=m;i++)
            if(q[i].kind==1)
                printf("%lld
    ",q[i].ans);
        return 0;
    }
  • 相关阅读:
    界面控件DevExpress WPF入门 表达式编辑器功能
    Telerik UI for WPF全新版本——拥有Office2019高对比度主题
    DevExpress报表控件v21.2 全新的Visual Studio报表设计器
    报告生成器FastReport .NET入门指南 在Linux中启动应用程序
    文档控件DevExpress Office File API v21.2 自定义字体加载引擎
    UI组件库Kendo UI for Angular入门 如何开始使用图表功能
    WPF界面工具Telerik UI for WPF入门级教程 设置一个主题(二)
    DevExtreme初级入门教程(React篇) TypeScript支持
    报表开发利器FastReport .NET v2022.1 添加关键对象和属性
    python项目打包(一) setup.py、Python源代码项目结构
  • 原文地址:https://www.cnblogs.com/FallDream/p/xunlian330.html
Copyright © 2011-2022 走看看