补题日记[2022杭电暑期多校2]K-DOS Card

Posted cls1277

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了补题日记[2022杭电暑期多校2]K-DOS Card相关的知识,希望对你有一定的参考价值。

Pro

https://acm.hdu.edu.cn/showproblem.php?pid=7160

Sol

因为要求四个数正负组合的答案,又因为下标递增,因此只有两种符号分配情况++--+-+-,针对这两种情况考虑如何维护出这种正负号组合。

将其拆分开就是+,-,++,+-,-+,--,+--,++-,+-+,-+-10种情况,左右线段树端点的组合刚好可以等于上面一个线段树的端点,即这么划分满足线段树的用法,因此使用线段树维护出这10个值与答案的两种情况,在pushup的时候进行从下往上更新。

易错点:因为线段树的非叶点更新时取子节点的最大值,因此这个端点初始化时应该为负数,而至于负数多少,需要提前计算(我测试使用-INT_MAX还不够,使用-1e18就对了。)

虽然此处在求答案时是左右相加,但是并不是平常意义上的相加或者取最大值,而是与pushup过程类似,相当于由两个查找的端点更新答案变量。因为可能存在使用两个线段树结点更新答案时会使答案更优的情况,这些情况都需要考虑到,而这种过程类似于pushup的过程,因此只需要用pushup的代码重载加号运算符即可(看代码)。

Code

//By cls1277
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
#define Fo(i,a,b) for(LL i=(a); i<=(b); i++)
#define Ro(i,b,a) for(LL i=(b); i>=(a); i--)
#define Eo(i,x,_) for(LL i=head[x]; i; i=_[i].next)
#define Ms(a,b) memset((a),(b),sizeof(a))
#define endl '\\n'
#define ls x<<1
#define rs x<<1|1

const LL maxn = 2e5+5;
LL n, q, a[maxn];

struct Seg 
    LL l, r;
    LL ans1, ans2;//++-- +-+-
    LL a[10];
    //0 1 2  3   4  5  6   7   8   9
    //+ - ++ +- -+ -- +-- ++- +-+ -+-
    Seg() 
        ans1 = ans2 = -1e18;
        Fo(i,0,9) a[i] = -1e18;
    
tree[maxn<<2];

Seg operator + (const Seg &x, const Seg &y) 
    Seg z;
    Fo(i,0,9) z.a[i] = max(x.a[i], y.a[i]);
    z.a[2] = max(z.a[2], x.a[0]+y.a[0]);
    z.a[3] = max(z.a[3], x.a[0]+y.a[1]);
    z.a[4] = max(z.a[4], x.a[1]+y.a[0]);
    z.a[5] = max(z.a[5], x.a[1]+y.a[1]);
    z.a[6] = max(z.a[6], x.a[0]+y.a[5], x.a[3]+y.a[1]);
    z.a[7] = max(z.a[7], x.a[0]+y.a[3], x.a[2]+y.a[1]);
    z.a[8] = max(z.a[8], x.a[0]+y.a[4], x.a[3]+y.a[0]);
    z.a[9] = max(z.a[9], x.a[1]+y.a[3], x.a[4]+y.a[1]);
    z.ans1 = max(x.ans1, y.ans1, x.a[0]+y.a[6], x.a[2]+y.a[5], x.a[7]+y.a[1]);
    z.ans2 = max(x.ans2, y.ans2, x.a[0]+y.a[9], x.a[3]+y.a[3], x.a[8]+y.a[1]);
    return z;


void pushup(LL x) 
    Fo(i,0,9) tree[x].a[i] = max(tree[ls].a[i], tree[rs].a[i]);
    tree[x].a[2] = max(tree[x].a[2], tree[ls].a[0]+tree[rs].a[0]);
    tree[x].a[3] = max(tree[x].a[3], tree[ls].a[0]+tree[rs].a[1]);
    tree[x].a[4] = max(tree[x].a[4], tree[ls].a[1]+tree[rs].a[0]);
    tree[x].a[5] = max(tree[x].a[5], tree[ls].a[1]+tree[rs].a[1]);
    tree[x].a[6] = max(tree[x].a[6], tree[ls].a[0]+tree[rs].a[5], tree[ls].a[3]+tree[rs].a[1]);
    tree[x].a[7] = max(tree[x].a[7], tree[ls].a[0]+tree[rs].a[3], tree[ls].a[2]+tree[rs].a[1]);
    tree[x].a[8] = max(tree[x].a[8], tree[ls].a[0]+tree[rs].a[4], tree[ls].a[3]+tree[rs].a[0]);
    tree[x].a[9] = max(tree[x].a[9], tree[ls].a[1]+tree[rs].a[3], tree[ls].a[4]+tree[rs].a[1]);
    tree[x].ans1 = max(tree[ls].ans1, tree[rs].ans1, tree[ls].a[0]+tree[rs].a[6], tree[ls].a[2]+tree[rs].a[5], tree[ls].a[7]+tree[rs].a[1]);
    tree[x].ans2 = max(tree[ls].ans2, tree[rs].ans2, tree[ls].a[0]+tree[rs].a[9], tree[ls].a[3]+tree[rs].a[3], tree[ls].a[8]+tree[rs].a[1]);


void build(LL x, LL l, LL r) 
    tree[x].l = l; tree[x].r = r;
    tree[x].ans1 = tree[x].ans2 = -1e18;
    Fo(i,0,9) tree[x].a[i] = -1e18;
    if(l==r) 
        tree[x].a[0] = a[l];
        tree[x].a[1] = -a[l];
        return ;
    
    LL mid = (l+r)>>1;
    build(ls, l, mid);
    build(rs, mid+1, r);
    pushup(x);


Seg query(LL x, LL l, LL r) 
    if(l<=tree[x].l&&r>=tree[x].r) return tree[x];
    LL mid = (tree[x].l+tree[x].r)>>1;
    Seg res;
    if(l<=mid) res = res+query(ls, l, r);
    if(r>mid) res = res+query(rs, l, r);
    return  res;


int main() 
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    #ifdef DEBUG
    freopen("data.txt","r",stdin);
    freopen("out.txt","w",stdout);
    #endif
    LL t; cin>>t;
    while(t--) 
        // Ms(tree, 0);
        cin>>n>>q;
        Fo(i,1,n) 
            cin>>a[i];
            a[i] *= a[i];
        
        build(1, 1, n);
        while(q--) 
            LL l, r; cin>>l>>r;
            Seg ans = query(1, l, r);
            cout<<max(ans.ans1, ans.ans2)<<endl;
        
    
    return 0;


以上是关于补题日记[2022杭电暑期多校2]K-DOS Card的主要内容,如果未能解决你的问题,请参考以下文章

补题日记[2022杭电暑期多校3]K-Taxi

补题日记[2022杭电暑期多校3]K-Taxi

补题日记[2022杭电暑期多校1]C-Backpack

补题日记[2022杭电暑期多校1]B-Dragon slayer

补题日记[2022杭电暑期多校3]B-Boss Rush

补题日记[2022杭电暑期多校3]B-Boss Rush