• 洛谷 P3437 [POI2006]TET-Tetris 3D


    二维线段树区间更新啊

    树套树的外层树,如果是线段树的话一般似乎不能打标记?(毕竟标记不好下传)

    然而起码对于这题是可以的...对于外层线段树,每个节点放两个内层线段树dat和setv,分别是得到的值和修改操作留下的标记。

    然后外层线段树要标记永久化...标记永久化之后,标记的定义不一样了。

    这道题里用dat[i]表示i节点表示的整段区间都达到的值,setv[i]表示i节点表示的区间的最大值

    (这两个的名字似乎反了?)

    这样进行修改操作的时候,更新所有经过的节点的setv(因为只要经过该点,那么该点表示的区间和目标区间一定有相交部分),更新被目标区间完全包含的区间所在节点的dat(自然整段都达到那个值了)

    进行查询操作的时候,"所有经过节点的dat"和"所有被目标区间完全包含的区间所在节点的setv"的最大值就是答案。

    二维都一样,只不过外层线段树的查询是对于内层线段树的给定区间查询/修改

    标记不下传

    (一眼看起来似乎不是很对?有些信息被遗漏了?然而的确是对的23333)

    (似乎修改和查询完全是对称的...)

    错误记录:71行少了分号后的两个语句导致WA一片

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<cstring>
     4 #define lc (num<<1)
     5 #define rc (num<<1|1)
     6 #define mid ((l+r)>>1)
     7 using namespace std;
     8 int n,m;
     9 namespace XXX
    10 {
    11     int L,R,x;
    12 struct Y
    13 {
    14     int dat[2100],setv[2100];
    15     //dat表示整段区间都达到的值,setv表示区间最大值
    16     void update(int l,int r,int num)
    17     {
    18         setv[num]=max(setv[num],x);
    19         if(L<=l&&r<=R)
    20         {
    21             dat[num]=max(dat[num],x);
    22             return;
    23         }
    24         if(L<=mid)    update(l,mid,lc);
    25         if(mid<R)    update(mid+1,r,rc);
    26     }
    27     int query(int l,int r,int num)
    28     {
    29         if(L<=l&&r<=R)    return setv[num];
    30         int ans=dat[num];
    31         if(L<=mid)    ans=max(ans,query(l,mid,lc));
    32         if(mid<R)    ans=max(ans,query(mid+1,r,rc));
    33         return ans;
    34     }
    35 };
    36 }
    37 int L,R,x;
    38 XXX::Y dat[2100],setv[2100];
    39 void update(int l,int r,int num)
    40 {
    41     XXX::x=x;
    42     setv[num].update(1,m,1);
    43     if(L<=l&&r<=R)
    44     {
    45         XXX::x=x;
    46         dat[num].update(1,m,1);
    47         return;
    48     }
    49     if(L<=mid)    update(l,mid,lc);
    50     if(mid<R)    update(mid+1,r,rc);
    51 }
    52 int query(int l,int r,int num)
    53 {
    54     if(L<=l&&r<=R)    return setv[num].query(1,m,1);
    55     int ans=dat[num].query(1,m,1);
    56     if(L<=mid)    ans=max(ans,query(l,mid,lc));
    57     if(mid<R)    ans=max(ans,query(mid+1,r,rc));
    58     return ans;
    59 }
    60 int main()
    61 {
    62     int Q,d,s,w,xx,yy;
    63     scanf("%d%d%d",&n,&m,&Q);
    64     while(Q--)
    65     {
    66         scanf("%d%d%d%d%d",&d,&s,&w,&xx,&yy);xx++;yy++;
    67         L=xx;R=xx+d-1;XXX::L=yy;XXX::R=yy+s-1;
    68         x=query(1,n,1)+w;//printf("%d
    ",x);
    69         update(1,n,1);
    70     }
    71     L=1;R=n;XXX::L=1;XXX::R=m;
    72     printf("%d",query(1,n,1));
    73     return 0;
    74 }
  • 相关阅读:
    Android系统启动过程分析
    android的logcat 用法整理
    git 使用详解(10) 远程分支
    android的logcat 用法整理
    android Binder工作流程
    android Binder工作流程
    git log 小结
    linux patch 命令小结
    windows 中 \r\n 区别于 类unix中的\n 疑问 迎刃而解
    Mysql Error Code : 1436 Thread stack overrun
  • 原文地址:https://www.cnblogs.com/hehe54321/p/8591707.html
Copyright © 2020-2023  润新知