HDU 5316 Magician (线段树,单值修改,微变形)
题意:给一个初始序列A[1,n],第j个数字代表精灵j的power值,有两种操作:(1)查询区间[L,R] (2)修改某个精灵的power值。
但,查询的是区间[L,R]中一个美丽子序列sub[l,r]的和,美丽子序列是从A[L,R]中挑出的一些数字,这些数字按升序排好序,每两个相邻数字(sub[a],sub[b])在A[L,R]中的下标的的奇偶性不同。sub中至少有一个元素。power值可能为负。
思路:
单值修改的线段树,比较简单的模板。主要的问题在,奇偶性如何满足?
对于一个区间,要从中挑出一些数且满足相邻两数的下标奇偶性不同,那么就有4种选择(奇,奇)(奇,偶)(偶,奇)(偶,偶),“奇偶”代表其开头和结束位置的下标的奇偶性。现在又有问题了,如何合并区间?
以奇结尾的就必须以偶开头,这样全部组合一下,继续维护这4个值即可。比如(奇,奇)+(偶,偶),或(奇,偶)+(偶,奇)这些组合都行。该注意的是,因为power还有负值,又必须选1个,所以还可能(奇,奇)被两个区间(奇,奇)(奇,奇)其中的一个更新,(偶,偶)同理。
问题又来了,查询的时候,怎么返回?
那就绑成一个结构体返回。又要注意的是,可能[L,R]必须拆成两个区间时,合并区间的操作又要再做一次再返回这个结构体。
#include <bits/stdc++.h>
#define LL long long
using namespace std;
const int N=; struct node
{
long long a[][]; //1表示奇数,0表示偶数
bool flag;
node(){a[][]=a[][]=a[][]=a[][]=-1e18;flag=;}
}point[N*]; void get_val(int cur)
{
for(int i=; i<; i++)
{
for(int j=; j<; j++)
{
point[cur].a[i][j]=max( point[cur*].a[i][j], point[cur*+].a[i][j]);
point[cur].a[i][j]=max( point[cur].a[i][j], point[cur*].a[i][]+point[cur*+].a[][j] );
point[cur].a[i][j]=max( point[cur].a[i][j], point[cur*].a[i][]+point[cur*+].a[][j] );
}
}
} void create_tree(int l, int r, int cur) //cur为当前结点下标
{
if(l==r)
{
LL tmp;
scanf("%lld",&tmp);
point[cur]=node();
point[cur].a[l&][l&]=tmp;
return ;
}
int mid=(l+r)/;
create_tree(l, mid, cur*);
create_tree(mid+, r, cur*+);
get_val(cur); //以孩子的值来更新自身的值
} void update(int l,int r,int cur,int a,LL w)
{
if(l==r)
{
point[cur]=node();
point[cur].a[l&][l&]=w;
return ;
}
int mid=(l+r)/;
if(a<=mid) update(l, mid, cur*, a, w); //在左边
else update(mid+, r, cur*+, a, w);
get_val(cur); //回溯时更新自身
} node query(int l,int r, int L,int R,int cur)
{
if(l==L && r==R) return point[cur];
int mid=(L+R)/;
if(r<=mid) return query(l,r, L,mid, cur*);
else if(l>mid) return query(l,r, mid+,R, cur*+);
else
{
node tmp=node(), a=node(), b=node();
a=query(l,mid, L,mid,cur*);
b=query(mid+,r, mid+,R,cur*+);
for(int i=; i<; i++)
{
for(int j=; j<; j++)
{
tmp.a[i][j]=max( a.a[i][j], b.a[i][j]);
tmp.a[i][j]=max( tmp.a[i][j], a.a[i][]+b.a[][j] );
tmp.a[i][j]=max( tmp.a[i][j], a.a[i][]+b.a[][j]);
}
}
return tmp;
}
} int main()
{
//freopen("input.txt", "r", stdin);
int t, n, q, L, R, op;
LL W;
cin>>t;
while(t--)
{
cin>>n>>q;
create_tree(, n, );
for(int i=; i<q; i++)
{
scanf("%d",&op);
if(op==) //修改
{
scanf("%d %lld", &L, &W);
update(, n, , L, W);
}
else //查询
{
scanf("%d %d", &L, &R);
node tmp=query( L, R, , n, );
LL ans1=max(tmp.a[][],tmp.a[][]);
LL ans2=max(tmp.a[][],tmp.a[][]);
printf("%lld\n",max(ans1,ans2) );
}
}
}
return ;
}
AC代码
HDU 5316 Magician (线段树,单值修改,微变形)的更多相关文章
- hdu 5316 Magician 线段树维护最大值
题目链接:Magician 题意: 给你一个长度为n的序列v,你需要对这个序列进行m次操作,操作一共有两种,输入格式为 type a b 1.如果type==0,你就需要输出[a,b]区间内的美丽序列 ...
- hdu 5316 Magician 线段树
链接:http://acm.hdu.edu.cn/showproblem.php? pid=5316 Magician Time Limit: 18000/9000 MS (Java/Others) ...
- HDU 5475(2015 ICPC上海站网络赛)--- An easy problem(线段树点修改)
题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=5475 Problem Description One day, a useless calculato ...
- 题解报告:hdu 1698 Just a Hook(线段树区间修改+lazy懒标记的运用)
Problem Description In the game of DotA, Pudge’s meat hook is actually the most horrible thing for m ...
- HDU - 1754 I Hate It (线段树点修改求最大值)
题意:有N个学生M条操作,0<N<=200000,0<M<5000,要么查询某区间内学生的最高分,要么更改某学生的成绩. 分析:原理和线段树点修改求和类似. #include& ...
- I Hate It(线段树点修改区间查询)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1754 I Hate It Time Limit: 9000/3000 MS (Java/Others) ...
- lintcode:线段树的修改
线段树的修改 对于一棵 最大线段树, 每个节点包含一个额外的 max 属性,用于存储该节点所代表区间的最大值. 设计一个 modify 的方法,接受三个参数 root. index 和 value.该 ...
- hdu 4031 attack 线段树区间更新
Attack Time Limit: 5000/3000 MS (Java/Others) Memory Limit: 65768/65768 K (Java/Others)Total Subm ...
- hdu 4288 离线线段树+间隔求和
Coder Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Su ...
- hdu 3016 dp+线段树
Man Down Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total S ...
随机推荐
- CSS 知识积累
一.关于定位 1.相对定位下,不需要设定块级元素的宽度,只需要设定高度,即可以使该块级元素自适应,如果内有固定高度子元素,可以不设高度.而且可以进行top left定位. 2.相对定位下,如果两个兄弟 ...
- SGU 113
113. Nearly prime numbers time limit per test: 0.25 sec. memory limit per test: 4096 KB Nearly prime ...
- GCD初步认识
//(1)用异步函数往并发队列中添加任务, //总结:同时开启三个子线程 - (void)test1 { //1.获得全局的并发队列 dispatch_queue_t queue = dispatch ...
- HDU 1116 || POJ 1386 || ZOJ 2016 Play on Words (欧拉回路+并查集)
题目链接 题意 : 有很多门,每个门上有很多磁盘,每个盘上一个单词,必须重新排列磁盘使得每个单词的第一个字母与前一个单词的最后一个字母相同.给你一组单词问能不能排成上述形式. 思路 :把每个单词看成有 ...
- 2013 ACM/ICPC Asia Regional Changsha Online - C Color Representation Conversion
这个纯粹是一个细节题啊!!! 由于某个地方的浮点数比较写错了,WA了无数次啊…… 代码如下: #include<iostream> #include<cstdio> #incl ...
- C# DES 加密 解密
//注意:密钥必须为8位 private const string m_strEncryptKey = "abcd1234"; /// <summary> /// 加密 ...
- VS2010/MFC编程入门之二(利用MFC向导生成单文档应用程序框架)
VS2010/MFC编程入门之二(利用MFC向导生成单文档应用程序框架)-软件开发-鸡啄米 http://www.jizhuomi.com/software/141.html 上一讲中讲了VS20 ...
- php 写入数据到MySQL以及从MySQL获取数据,页面出现乱码的解决方法
现象如标题. 解决思路: 1确定数据库charset是否是utf-8 a. charset不是utf-8 1, 更改数据库charset为utf-8 ALTER DATABASE db_name DE ...
- 【转】RESTful Web Services初探
近几年,RESTful Web Services渐渐开始流行,大量用于解决异构系统间的通信问题.很多网站和应用提供的API,都是基于RESTful风格的Web Services,比较著名的包括Twit ...
- 在CentOS下面编译WizNote Qt Project
编译环境 CentOS 64位 Desktop 版本:6.5 编译前的准备: CentOS的用户默认没有root权限,如果当前用户没有权限root,则可以在终端里面执行下面的命令: su root s ...