zoukankan      html  css  js  c++  java
  • ZOJ 3299 线段树 离散化

    本来是个很简单的题目,难住我的主要是这么几点

    1.它所有的点都是坐标,不是实际的砖块,1,3指的是1-2 2-3的砖块。。。后来就是用1 代表1-2 ,2代表2-3.。。。。,这样的话,每次读入的数据,都把r--

    就行,然后在实际的砖块数就是 x[r+1]-x[l]。

    2.我动手太快,没想清楚它是叠层型,即每次读入砖块坐标,都是往原有砖块的基础上++,这样的话,懒惰标记,就也一定是每次++,这里我WA了好久,一开始没想清楚,没按叠层来更新懒惰标记。。

    3.有个地方超级难以想到,就是在最后query木板能承载多少砖块的时候,用个flag标记好已经完全清空的node,因为询问有多次,下次再遇到这个node的时候,直接return 0,我一开始没想明白,觉得这个去掉也没关系。。后来发现,因为延迟标记的问题某个节点如果被清空,其子节点可能尚未更新,而且延迟非常严重,可能连初始的砖块都还没更新,弄个极端的例子,直接初始落下砖块1-8,然后只有最顶上的节点有砖块,底下全没有,这个时候你开始插入板子,第一次访问1-8,肯定是正确的结果,再次插板访问1-8中的某一个节点,比如5-8,此时它连上一次的砖块落下那个延迟标记都还没更新,你即便pushdown了,也是第一次插板1-8之前的状态了,绝逼是错的啊。所以我试了好多次,终于明白这个确实是关键。

    4.其实离散化反而在这个题目里面很不起眼了,就是最普通的离散化,而且中间不必手动插点也能过。。当然还是手动插一插比较好

    5.这个题目卡内存超级BT啊。。我就多开了那么一些,就MLE,少开了一点,就SF越界,我简直无语啊。。

    改来改去,代码写的真心挫。。。求不喷。。

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #define lson rt<<1,l,mid
    #define rson rt<<1|1,mid+1,r
    #define N 110010
    using namespace std;
    long long d[N*18];
    bool flag[N*18];
    int pd[N*18];
    int a[N],b[N];
    int x[N*8];
    struct node
    {
        int ax;
        int bx;
        int h;
        int id;
        long long ans;
    } bd[N];
    void getup(int rt)
    {
        d[rt]=d[rt<<1]+d[rt<<1|1];
    }
    void build(int rt,int l,int r)
    {
        d[rt]=0;
        flag[rt]=false;
        pd[rt]=0;
        if (l>=r)
        {
            return;
        }
        int mid=(l+r)>>1;
        build(lson);
        build(rson);
        //getup(rt);
    }
    void pushdown(int rt,int l,int r)
    {
        if (l>=r) return;
        int ll=rt<<1,rr=rt<<1|1;
        int mid=(l+r)>>1;
        pd[ll]+=pd[rt];
        pd[rr]+=pd[rt];
        d[ll]+=(long long)pd[rt]*(x[mid+1]-x[l]);
        d[rr]+=(long long)pd[rt]*(x[r+1]-x[mid+1]);
        pd[rt]=0;
    }
    void fix(int L,int R,int col,int rt,int l,int r)
    {
        
        if (L<=l && r<=R)
        {
            d[rt]+=(long long)(x[r+1]-x[l]);
            pd[rt]+=col;
            return;
        }
        pushdown(rt,l,r);
        int mid=(l+r)>>1;
        if (L<=mid) fix(L,R,col,lson);
        if (R>mid) fix(L,R,col,rson);
        getup(rt);
    }
    long long query(int L,int R,int rt,int l,int r)
    {
        
        if (flag[rt]) return 0;//这里是关键,详见要点3
        if (L<=l && r<=R)
        {
            flag[rt]=true;
            long long temp;
            temp=d[rt];
            d[rt]=0;
            pd[rt]=0;
            return temp;
        }
        pushdown(rt,l,r);
        int mid=(l+r)>>1;
        long long ret=0;
        if (L<=mid) ret+=query(L,R,lson);
        if (R>mid) ret+=query(L,R,rson);
        getup(rt);
        return ret;
    }
    int bs(int data,int l,int r)
    {
        int mid;
        while (l<r)
        {
            mid=(l+r)>>1;
            if (x[mid]==data) return mid;
            if (x[mid]<data) l=mid+1;
            else
                r=mid;
        }
        return l;
    }
    bool cmp(node a,node b)
    {
        return a.h>b.h;
    }
    bool cmp2(node a,node b)
    {
        return a.id<b.id;
    }
    int main()
    {
        int n,m;
        while (scanf("%d%d",&n,&m)!=EOF)
        {
            int i,j;
            int mcur=0;
            for (i=1; i<=n; i++)
            {
                scanf("%d%d",&a[i],&b[i]);
                if (a[i]>b[i])
                {
                    int tt=a[i];
                    a[i]=b[i];
                    b[i]=tt;
                }
                //b[i]--;
                x[++mcur]=a[i];
                x[++mcur]=b[i];
            }
            for (j=1; j<=m; j++)
            {
                scanf("%d%d%d",&bd[j].ax,&bd[j].bx,&bd[j].h);
                bd[j].id=j;
                if (bd[j].ax>bd[j].bx)
                {
                    int t2=bd[j].ax;
                    bd[j].ax=bd[j].bx;
                    bd[j].bx=t2;
                }
                //bd[j].bx--;
                x[++mcur]=bd[j].ax;
                x[++mcur]=bd[j].bx;
            }
            sort(x+1,x+1+mcur);
            int cur=1;
            for (i=2; i<=mcur; i++)
            {
                if (x[i]!=x[i-1]) x[++cur]=x[i];
            }
            int temp=cur;
    
            for (i=2; i<=temp; i++)
            {
                if (x[i]-x[i-1]>1) x[++cur]=x[i-1]+1;
                //if (x[i]-x[i-1]>2) x[++cur]=x[i]-1;
            }
    
            sort(x+1,x+1+cur);
    
            //for (i=1; i<=cur; i++)
            //    cout<<i<<" "<<x[i]<<endl;
    
            build(1,1,cur);
            int fa,fb;
            for (i=1; i<=n; i++)
            {
                fa=bs(a[i],1,cur);
                fb=bs(b[i],1,cur);
                if (fa>fb){
                    int t3=fa;
                    fa=fb;
                    fb=t3;
                }
                if (fb>fa) fb--;
                fix(fa,fb,1,1,1,cur);
            }
            //cout<<"Pass"<<endl;
            sort(bd+1,bd+1+m,cmp);
            for (i=1; i<=m; i++)
            {
                fa=bs(bd[i].ax,1,cur);
                fb=bs(bd[i].bx,1,cur);
                if (fa>fb){
                    int t4=fa;
                    fa=fb;
                    fb=t4;
                }
                if(fb>fa) fb--;
                long long tt=query(fa,fb,1,1,cur);
                bd[i].ans=tt;
            }
            //cout<<"Pass2"<<endl;
            sort(bd+1,bd+1+m,cmp2);
            for (j=1; j<=m; j++)
            {
                printf("%lld
    ",bd[j].ans);
            }
            putchar('
    ');
        }
        return 0;
    }
  • 相关阅读:
    移动端文本编辑器
    jquery移动端日期插件
    Spring 4集成 Quartz2(转)
    json 特殊字符 javascript 特殊字符处理(转载)
    解决使用JavaScriptConvert转换对象为Json时,中文和&符号被转码的问题
    RFID的winform程序心得2
    异步编程模型
    DataGridView获取或者设置当前单元格的内容
    DataGridView修改数据并传到数据库
    把存储过程结果集SELECT INTO到临时表
  • 原文地址:https://www.cnblogs.com/kkrisen/p/3419252.html
Copyright © 2011-2022 走看看