• 洛谷 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 }
  • 相关阅读:
    关于OS命令注入的闭合问题
    PostgreSQL远程连接配置
    IBatis 配置各种数据库
    iOS开发--图片轮播
    iOS开发--UILabel根据内容自动调整高度
    iOS开发--底部按钮和应用图标显示未读消息
    常用软件安装及VS插件工具
    Git入门
    部署时,出现用户代码未处理 System.Security.Cryptography.CryptographicException 错误解决方法
    .NET 互联网技术简介
  • 原文地址:https://www.cnblogs.com/hehe54321/p/8591707.html
Copyright © 2020-2023  润新知