[JSOI2009]等差数列
链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1558
题解:
考虑这么用线段树进行维护,由于他有区间修改等差数列
很容易想到可以用差分数组来维护(这东西经常和数据结构用在一起)
那么每一次的区间修改就变成了单点修改
另外我们可以利用线段树来维护:
h---t区间等差数列个数,h----(t-1)区间等差数列个数,(h+1)---t区间等差数列个数
为了维护这三个值,要引入(h+1)-----(t-1)(这个转移非常巧妙)
为什么要维护这些呢,因为我们算一个就可以发现
当他们不是一个等差数列时,区间中有一个数是没有用的
由于进行了差分,等差数列其实就是差分数组的值相同
bzoj re了 并不知道为什么 对拍是对的
代码:
#include <bits/stdc++.h>
#define maxn 311111
#define mid (p[x].h+p[x].t)/2
using namespace std;
int n,m,a[maxn*],b[maxn*];
struct re
{
int h,t,sum,sum1,sum2,sum3,lazy,hnum,tnum;
}p[maxn*];
struct ree
{
int sum,sum1,sum2;
};
void updata(int x)
{
p[x].sum=min(p[x*].sum2+p[x*+].sum,p[x*].sum+p[x*+].sum1);
p[x].sum1=min(p[x*].sum3+p[x*+].sum,p[x*].sum1+p[x*+].sum1);
p[x].sum2=min(p[x*].sum2+p[x*+].sum2,p[x*].sum+p[x*+].sum3);
p[x].sum3=min(p[x*].sum3+p[x*+].sum2,p[x*].sum1+p[x*+].sum3);
if (p[x*].tnum==p[x*+].hnum)
{
p[x].sum=min(p[x].sum,p[x*].sum+p[x*+].sum-);
p[x].sum1=min(p[x].sum1,p[x*].sum1+p[x*+].sum-);
p[x].sum2=min(p[x].sum2,p[x*].sum+p[x*+].sum2-);
p[x].sum3=min(p[x].sum3,p[x*].sum1+p[x*+].sum2-);
}
}
void build(int x,int h,int t)
{
p[x].h=h; p[x].t=t;
p[x].hnum=b[p[x].h];
p[x].tnum=b[p[x].t];
if (p[x].h==p[x].t)
{
p[x].sum=p[x].sum1=p[x].sum2=;p[x].sum3=; return;
}
build(x*,h,mid); build(x*+,mid+,t);
updata(x);
}
void down(int x)
{
if (p[x].lazy)
{
p[x].hnum+=p[x].lazy;
p[x].tnum+=p[x].lazy;
if (p[x].h!=p[x].t)
{
p[x*].lazy+=p[x].lazy;
p[x*+].lazy+=p[x].lazy;
}
p[x].lazy=;
}
}
void change(int x,int h,int t,int sum)
{
down(x);
if (p[x].h>t||p[x].t<h) return;
if (h<=p[x].h&&p[x].t<=t)
{
p[x].lazy+=sum; down(x);
return;
}
if (p[x].h<=t&&p[x].h>=h) p[x].hnum+=sum;
if (p[x].t<=t&&p[x].t>=h) p[x].tnum+=sum;
change(x*,h,t,sum);
change(x*+,h,t,sum);
updata(x);
}
re query(int x,int h,int t)
{
down(x);
re now;
if (h<=p[x].h&&p[x].t<=t)
{
now=p[x];
return(now);
}
if (mid+>t) return(query(x*,h,t));
if (mid<h) return(query(x*+,h,t));
re a=query(x*,h,t),b=query(x*+,h,t);
now.sum=min(a.sum2+b.sum,a.sum+b.sum1);
now.sum1=min(a.sum3+b.sum,a.sum1+b.sum1);
now.sum2=min(a.sum2+b.sum2,a.sum+b.sum3);
now.sum3=min(a.sum3+b.sum2,a.sum1+b.sum3);
if (p[x*].tnum==p[x*+].hnum)
{
now.sum=min(now.sum,a.sum+b.sum-);
now.sum1=min(now.sum1,a.sum1+b.sum-);
now.sum2=min(now.sum2,a.sum+b.sum2-);
now.sum3=min(now.sum3,a.sum1+b.sum2-);
}
return(now);
}
int main()
{
freopen("noip.in","r",stdin);
freopen("noip.out","w",stdout);
std::ios::sync_with_stdio(false);
cin>>n;
for (int i=;i<=n;i++)
{
cin>>a[i];
b[i-a]=a[i]-a[i-];
}
build(,,n-);
//for (int i=1;i<=2*n;i++){cout<<p[i].h<<" "<<p[i].t<<" "<<p[i].sum<<endl;}
cin>>m;
char c;
for (int i=;i<=m;i++)
{
int a1,b1,c1,d1;
cin>>c;
if (c=='A')
{
cin>>a1>>b1>>c1>>d1;
change(,a1,b1-,d1);
if (a1!=) change(,a1-,a1-,c1);
change(,b1,b1,-(c1+(b1-a1)*d1));
}
if (c=='B')
{
cin>>a1>>b1; re x;
if (a1!=b1) x=query(,a1,b1-);
else x.sum=;
cout<<x.sum<<endl;
}
}
}
[JSOI2009]等差数列的更多相关文章
- bzoj 1558: [JSOI2009]等差数列
Description Solution 把原数组变为差分数组,然后剩下的就十分显然了 区间查询用线段树维护 修改操作就是区间加法和两个单点修改 一个等差数列实际上就是 开头一个数字+数值相等的一段 ...
- [bzoj1558][JSOI2009]等差数列
题目:给定n个数,m个操作,每次给一段区间加一个等差数列或者询问一段区间至少要用多少个等差数列来表示.$n,m\leqslant 10^{5}$ 题解:老套路,维护差分数组,修改操作变成了两个单点加和 ...
- 洛谷P4243/bzoj1558 [JSOI2009]等差数列(线段树维护差分+爆炸恶心的合并)
题面 首先感谢这篇题解,是思路来源 看到等差数列,就会想到差分,又有区间加,很容易想到线段树维护差分.再注意点细节,\(A\)操作完美解决 然后就是爆炸恶心的\(B\)操作,之前看一堆题解的解释都不怎 ...
- BZOJ.1558.[JSOI2009]等差数列(线段树 差分)
BZOJ 洛谷 首先可以把原序列\(A_i\)转化成差分序列\(B_i\)去做. 这样对于区间加一个等差数列\((l,r,a_0,d)\),就可以转化为\(B_{l-1}\)+=\(a_0\),\(B ...
- BZOJ1558 [JSOI2009]等差数列 【线段树】
题目链接 BZOJ1558 题解 等差数列,当然是差分一下 差分值相同的连续位置形成等差数列,我们所选的两个等差数列之间可以有一个位置舍弃 例如: \(1 \; 2 \; 3 \; 6 \; 8 \; ...
- JSOI2009 等差数列 和 算术天才⑨与等差数列 和 CH4302 Interval GCD
等差数列 为了检验学生的掌握情况,jyy布置了一道习题:给定一个长度为N(1≤N≤100,000)的数列,初始时第i个数为vi(vi是整数,−100,000≤vi≤100,000),学生们要按照jyy ...
- luogu P4243 [JSOI2009]等差数列 题解
前言: 这题真ex... 强烈谴责在题解里面放毒瘤题链接的屑出题人! 吐 ️ 解析: 这题分成两步走. 首先,既然题目中的修改操作是区间加等差数列,那么就容易想到在差分数组上进行操作. 然后就是相当恶 ...
- Noip前的大抱佛脚----赛前任务
赛前任务 tags:任务清单 前言 现在xzy太弱了,而且他最近越来越弱了,天天被爆踩,天天被爆踩 题单不会在作业部落发布,所以可(yi)能(ding)会不及时更新 省选前的练习莫名其妙地成为了Noi ...
- bzoj AC倒序
Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...
随机推荐
- MySQL锁解决并发问题详解
文章分为以下几个要点 问题描述以及解决过程 MySQL锁机制 数据库加锁分析 下面讨论的都是基于MySQL的InnoDB. 0. 问题描述以及解决过程 因为涉及到公司利益问题,所以下面很多代码和数据库 ...
- Nginx Server 配置
http { include mime.types; // 主模块:实现对配置文件包含的文件设定,可以减少主配置文件的复杂度: default_type application/octet-strea ...
- 把ui界面加入到工程中
第一步 from untitled import Ui_Form untitled是ui转化成py的文件名:Ui_Form是转换后的类名 第二步 把Ui_Form做为工程的父类 class ...
- ado.net 访问excel
1 类:OleDbConnection ... 2 connection string : Provider=Microsoft.ACE.OLEDB.12.0;Data Source={excelPa ...
- yolov3实践(一)
很多博友看了我的第一篇博客yolo类检测算法解析——yolo v3,对其有了一定的认识和了解,但是并没有贴出代码和运行效果,略显苍白.因此在把篇博客理论的基础上,造就了第一篇实践文章,也就是本文.只要 ...
- luogu P1486 [NOI2004]郁闷的出纳员
一万年以后终于调过了这题 这道题主要是维护一个有序的集合(吧),所以使用平衡树(我这里用\(Splay\)) 记录一个变量\(ff\)(雾),表示所有工资的变化量 对于\(I\)操作,如果初始工资大于 ...
- 第16月第5天 performSelector afterDelay cancel dispatch_semaphore_wait
1. //不延时,可能会导致界面黑屏并卡住一会 [self performSelector:@selector(startScan) withObject:nil afterDelay:0.3]; - ...
- VS2012 安装番茄插件
1.visual assist x 1929_大番茄.rar 下载地址: http://pan.baidu.com/s/1qXOUuJE 网盘提取密码: 3mka 文件解压密码: eg5p 2.安装完 ...
- oracle建包,函数demo
create table BOOK ( BOOK_ID NUMBER(10), BOOK_NAME VARCHAR2(10) ); create or replace package chen_pac ...
- linux查看操作系统的版本
内核信息 uname -a localhost.localdomain:所在主机的主机名,与主机配置文件/etc/hosts内容一致 2.4.20-8#1:内核版本号 Thu Mar 13 17:18 ...