杭电多校第二场 DOS Card

评价一下这道题:我写过最爽的线段树题。

这道题真的非常令人身心愉悦,非常厉害的一道线段树入门题。我写这个一次调试都没有,过了样例就交了就过了,一切都是行云流水。

这道题的代码非常好看,也非常好写。

题面:

对序列 \(a\),回答 \(q\) 次询问:

  • 给定长度至少为 \(4\) 的区间 \([L,R]\),在区间内选择 \(1\) 对 \((a_i,a_j)(L\leq i<j\leq R)\) 可以获取分数 \((a_i+a_j)(a_i-a_j)\) ,计算选择 \(2\) 对可以获取的最大分数之和。

注意:你选择的 \(2\) 对共 \(4\) 个数中不能有重复的位置

做法:

化为:选 \(2\) 对数,使得前面的数的平方减后面的数的平方之和最大。

\(a\) 直接变成原数的平方。

发现这 \(4\) 个数如果令加为 \(1\),令减为 \(0\),则合法的 \(4\) 个数的顺序只有 \(2\) 种:\(1010\) 和 \(1100\)。

然后线段树维护。对于一个区间,维护这两个顺序,需要枚举中间点,左边取左儿子区间的值,右边取右儿子区间的值。

然后也要维护这些更小的值。就先大型分类讨论一波(其实很好想),然后开写。

代码:

点击查看代码
#include <bits/stdc++.h>
static char buf[1000000],*p1=buf,*p2=buf,obuf[1000000],*p3=obuf;
#define getchar() p1==p2&&(p2=(p1=buf)+fread(buf,1,1000000,stdin),p1==p2)?EOF:*p1++
#define putchar(x) (p3-obuf<1000000)?(*p3++=x):(fwrite(obuf,p3-obuf,1,stdout),p3=obuf,*p3++=x)
template<typename item>
inline void read(register item &x)
{
bool flag=false;
x=0;register char c=getchar();
while(c<'0'||c>'9')
{
if(c=='-')
flag=true;
c=getchar();
}
while(c>='0'&&c<='9')x=(x<<3)+(x<<1)+(c^48),c=getchar();
if(flag)
x=-x;
}
static char cc[10000];
template<typename item>
inline void print(register item x)
{
if(x==0)
{
cc[0]='0';
putchar(cc[0]);
return;
}
if(x<0)
{
cc[0]='-';
putchar(cc[0]);
x=-x;
}
register long long len=0;
while(x)cc[len++]=x%10+'0',x/=10;
while(len--)putchar(cc[len]);
}
long long max(long long a,long long b)
{
return a>b?a:b;
}
const int MAXN=1e6+50;
struct Tree
{
long long a1,a0,
a11,a00,a10,a01,
a010,a101,a100,a110,
a1010,a1100;
}tr[MAXN];
Tree Merge(Tree x,Tree y)
{
Tree z;
//Len1:
z.a0=max(x.a0,y.a0);
z.a1=max(x.a1,y.a1);
//Len2:
z.a11=max(x.a11,max(x.a1+y.a1,y.a11));
z.a00=max(x.a00,max(x.a0+y.a0,y.a00));
z.a10=max(x.a10,max(x.a1+y.a0,y.a10));
z.a01=max(x.a01,max(x.a0+y.a1,y.a01));
//Len3:
z.a010=max(x.a010,max(x.a01+y.a0,max(x.a0+y.a10,y.a010)));
z.a101=max(x.a101,max(x.a10+y.a1,max(x.a1+y.a01,y.a101)));
z.a100=max(x.a100,max(x.a10+y.a0,max(x.a1+y.a00,y.a100)));
z.a110=max(x.a110,max(x.a11+y.a0,max(x.a1+y.a10,y.a110)));
//Len4:
z.a1010=max(x.a1010,max(x.a101+y.a0,max(x.a10+y.a10,max(x.a1+y.a010,y.a1010))));
z.a1100=max(x.a1100,max(x.a110+y.a0,max(x.a11+y.a00,max(x.a1+y.a100,y.a1100))));
return z;
}
long long a[MAXN];
void Build(int u,int l,int r)
{
if(l==r)
{
tr[u].a0=-a[l];
tr[u].a1=a[l];
tr[u].a00=tr[u].a01=tr[u].a10=tr[u].a11=-1e18;
tr[u].a010=tr[u].a100=tr[u].a101=tr[u].a110=-1e18;
tr[u].a1010=tr[u].a1100=-1e18;
return;
}
int Mid=l+r>>1;
Build(u<<1,l,Mid);
Build(u<<1|1,Mid+1,r);
tr[u]=Merge(tr[u<<1],tr[u<<1|1]);
} Tree Query(int u,int l,int r,int x,int y)
{
if(x<=l&&r<=y)
{
return tr[u];
}
int Mid=l+r>>1;
if((x<=Mid)&&(y>=Mid+1))
{
return Merge(Query(u<<1,l,Mid,x,y),Query(u<<1|1,Mid+1,r,x,y));
}
if(x<=Mid)
{
return Query(u<<1,l,Mid,x,y);
}
if(y>=Mid+1)
{
return Query(u<<1|1,Mid+1,r,x,y);
}
}
int N,Q;
int main()
{
int T;
read(T);
while(T--)
{
read(N);
read(Q);
for(int i=1;i<=N;i++)
{
read(a[i]);
a[i]*=a[i];
}
Build(1,1,N);
while(Q--)
{
int l,r;
read(l);
read(r);
Tree ans=Query(1,1,N,l,r);
print(max(ans.a1010,ans.a1100));
putchar('\n');
}
} fwrite(obuf,p3-obuf,1,stdout);
}

杭电多校第二场 DOS Card的更多相关文章

  1. 2018 Multi-University Training Contest 2 杭电多校第二场

    开始逐渐习惯被多校虐orz  菜是原罪 1004  Game    (hdoj 6312) 链接:http://acm.hdu.edu.cn/showproblem.php?pid=6312 虽然披着 ...

  2. 2018杭电多校第二场1003(DFS,欧拉回路)

    #include<bits/stdc++.h>using namespace std;int n,m;int x,y;int num,cnt;int degree[100007],vis[ ...

  3. 2019杭电多校第二场hdu6601 Keen On Everything But Triangle

    Keen On Everything But Triangle 题目传送门 解题思路 利用主席树求区间第k小,先求区间内最大的值,再求第二大,第三大--直到找到连续的三个数可以构成一个三角形.因为对于 ...

  4. 2019杭电多校第二场hdu6602 Longest Subarray(线段树)

    Longest Subarray 题目传送门 解题思路 本题求一个最大的子区间,满足区间内的数字要么出现次数大于等于k次,要么没出现过.给定区间内的数字范围是1~c. 如果r为右边界,对于一种数字x, ...

  5. 杭电多校第二场 1005 hack it

    题意: 构造一个n*n 的 01 矩阵, 0 < n < 2001,  矩阵需要满足没有一个子矩阵的4个角都是1,并且矩阵内1的个数至少有85000个. 题解:数论构造题 参考From 代 ...

  6. 杭电多校第二场 hdu 6315 Naive Operations 线段树变形

    Naive Operations Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 502768/502768 K (Java/Other ...

  7. hdu6312 2018杭电多校第二场 1004 D Game 博弈

    Game Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submis ...

  8. 2019年杭电多校第二场 1008题Harmonious Army(HDU6598+最小割+建图)

    题目链接 传送门 题意 有\(n\)个士兵,要你给他们分配职业.有\(m\)对关系,对于某一对关系\(u,v\),如果同为勇士则总能力增加\(a\),同法师则增加\(c\),一个勇士一个法师增加\(\ ...

  9. 2019年杭电多校第二场 1012题Longest Subarray(HDU6602+线段树)

    题目链接 传送门 题意 要你找一个最长的区间使得区间内每一个数出现次数都大于等于\(K\). 思路 我们通过固定右端点考虑每个左端点的情况. 首先对于每个位置,我们用线段树来维护它作为\(C\)种元素 ...

  10. 2019年杭电多校第二场 1002题Beauty Of Unimodal Sequence(LIS+单调栈)

    题目链接 传送门 思路 首先我们对\(a\)正反各跑一边\(LIS\),记录每个位置在前一半的\(LIS\)中应该放的位置\(ans1[i]\),后一半的位置\(ans2[i]\). 对于字典序最小的 ...

随机推荐

  1. JUC源码学习笔记8——ConcurrentHashMap源码分析1 如何实现低粒度锁的插入,如何实现统计元素个数,如何实现并发扩容迁移

    源码基于jdk1.8 这一片主要讲述ConcurrentHashMap如何实现低粒度锁的插入,如何实现统计元素个数,如何实现并发扩容迁移 系列文章目录和关于我 一丶ConcurrentHashMap概 ...

  2. STM32F407 学习 (0) 各种外设功能 (上)

      本文对正点原子STM32F4探索者的基本功能及外设作最基本的介绍,随笔者本人的学习进程(基本按照正点原子)而不定时更新,起到总结的作用. 一.HAL库编写程序的运行逻辑   HAL库函数(如stm ...

  3. 一文快速入门任务调度框架-Quartz

    前言 还不会 Quartz?如果你还没有接触过Quartz,那么你可能错过了一个很棒的任务调度框架!Quartz 提供了一种灵活.可靠的方式来管理和执行定时任务,让咱们的定时任务更加优雅.本篇文章将为 ...

  4. 记一次 .NET 某手术室行为信息系统 内存泄露分析

    一:背景 1. 讲故事 昨天有位朋友找到我,说他的程序内存存在泄露导致系统特别卡,大地址也开了,让我帮忙看一下怎么回事?今天上午看了下dump,感觉挺有意思,在我的分析之旅中此类问题也蛮少见,算是完善 ...

  5. internal java compiler error

    1.导入Maven项目运行报错:  解决方法:找到File->Settings  修改配置 再次运行就可以了.

  6. Mybatis-Plus如何自定义SQL注入器?

    有关Mybatis-Plus常用功能之前有做过一篇总结: MyBatisPlus常用功能总结!(附项目示例) 一.什么是SQL注入器 我们在使用Mybatis-Plus时,dao层都会去继承BaseM ...

  7. HTML、 input;、accept 属性-规定能够通过文件上传进行提交的文件类型

    定义和用法 文章地址: http://www.w3school.com.cn/tags/att_input_accept.asp accept 属性规定了可通过文件上传提交的服务器接受的文件类型. 注 ...

  8. SRAM 测试总结

    SoC随着工艺进步设计复杂度增加,embeded sram也越来越多.在40nm SoC产品Sram一般在20Mbits左右,当工艺发展到28nm时Sram就增加到100Mbits.如果考虑AI产品, ...

  9. Java的final修饰符

    final 实例域 可以将实例域定义为 final.对于 final 域来说,构建对象时必须初始化 final 实例域,构造对象之后就不允许改变 final 实例域的值了.也就是说,必须确保在每一个构 ...

  10. [Opencv-C++] 2. Opencv入门

    一.显示图像 从磁盘加载并在屏幕上显示一幅图像的简单Opencv程序 //Example 2-1. A simple OpenCV program that loads an image from d ...