F. Heroes of Making Magic III

time limit per test:3 seconds

memory limit per test:256 megabytes

input:standard input

output:standard output

I’m strolling on sunshine, yeah-ah! And doesn’t it feel good! Well, it certainly feels good for our Heroes of Making Magic, who are casually walking on a one-directional road, fighting imps. Imps are weak and feeble creatures and they are not good at much. However, Heroes enjoy fighting them. For fun, if nothing else.

Our Hero, Ignatius, simply adores imps. He is observing a line of imps, represented as a zero-indexed array of integers a of length n, where ai denotes the number of imps at the i-th position. Sometimes, imps can appear out of nowhere. When heroes fight imps, they select a segment of the line, start at one end of the segment, and finish on the other end, without ever exiting the segment. They can move exactly one cell left or right from their current position and when they do so, they defeat one imp on the cell that they moved to, so, the number of imps on that cell decreases by one. This also applies when heroes appear at one end of the segment, at the beginning of their walk.

Their goal is to defeat all imps on the segment, without ever moving to an empty cell in it (without imps), since they would get bored. Since Ignatius loves imps, he doesn’t really want to fight them, so no imps are harmed during the events of this task. However, he would like you to tell him whether it would be possible for him to clear a certain segment of imps in the above mentioned way if he wanted to.

You are given q queries, which have two types:

  • a b k — denotes that k imps appear at each cell from the interval [a, b]
  • a b - asks whether Ignatius could defeat all imps on the interval [a, b] in the way described above

Input

The first line contains a single integer n (1 ≤ n ≤ 200 000), the length of the array a. The following line contains n integersa1, a2, ..., an (0 ≤ ai ≤ 5 000), the initial number of imps in each cell. The third line contains a single integer q (1 ≤ q ≤ 300 000), the number of queries. The remaining q lines contain one query each. Each query is provided by integers ab and, possibly, k(0 ≤ a ≤ b < n, 0 ≤ k ≤ 5 000).

Output

For each second type of query output 1 if it is possible to clear the segment, and 0 if it is not.

Example

input
3
2 2 2
3
2 0 2
1 1 1 1
2 0 2
output
0
1

Note

For the first query, one can easily check that it is indeed impossible to get from the first to the last cell while clearing everything. After we add 1 to the second position, we can clear the segment, for example by moving in the following way: .

Solution

题目大意:

给定区间[0,N-1],支持两种操作:

1.区间[l,r]权值+K

2.区间是否可以删光(这里移动时不允许移动到区间之外)

这里可以删光的含义是:从一个格,可以向左/右移动一格,每移动一步,必须使左/右权值-1,当一个地方权值为0时,无法向其移动,删光即能否按照这种移动方式将这个区间中的所有权值删光。

区间上的问题显然可以考虑用线段树来实现。

问题在于这种移动方式,我们不妨考虑其性质。

对于询问一个区间是否能删光,不同的移动方法都有可能能完成,但为了方便我们只考虑其中一种方法。

对于区间$[l,r]$我们从$l$开始移动,我们就先在$l$和$l+1$之间来回,直到$l$清空,我们再在$l+1$和$l+2$之间来回,直到$l+1$清空,如此直到$r-1$和$r$

那么这样能够清空所有位置的权值的条件是:

$$a_{l}>=1$$

$$a_{l+1}-a_{l}>=0$$

$$a_{l+2}-(a_{l+1}-a_{l}+1)>=0$$

$$......$$

那么我们化简一下所有的式子可以得到:

$$a_{l}>=1$$

$$a_{l+1}-a_{l}>=0$$

$$a_{l+2}-a_{l+1}+a_{l}>=1$$

$$......$$

观察一下不等式右边,发现和项数的奇偶有关。

那么我们就可以得到一个通式:

$$a_{r}-a{r-1}+a{r-2}-a_{r-3}+...a_{l}>=[(r-l+1)mod1==0] $$

然后我们很直观的想法就是用线段树去维护这个东西,并且能分奇偶维护更加方便。

问题在于如何维护这个东西,我们做差,另$d_{i}=a_{1}-a{2}+a{3}...$

我们就可以利用这个东西,计算一个区间的值。 所以我们用线段树去维护这个东西。

对于一个区间$[l,r]$这个区间的值$D[l,r]$可以通过$d$来计算

然后我们按照奇偶分别维护,就可以了。

Code

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
#define LL long long
inline int read()
{
int x=,f=; char ch=getchar();
while (ch<'' || ch>'') {if (ch=='-') f=-; ch=getchar();}
while (ch>='' && ch<='') {x=x*+ch-''; ch=getchar();}
return x*f;
}
#define MAXN 300010
#define INF 0x7fffffff
int N,Q,a[MAXN],d[MAXN];
namespace SegmentTree
{
struct SegmentTreeNode{int l,r,size; LL sum,tag[],D[]; bool f;}tree[MAXN<<];
#define ls now<<1
#define rs now<<1|1
inline void Update(int now,bool o)
{
tree[now].D[]=min(tree[ls].D[],tree[rs].D[o]);
tree[now].D[]=min(tree[ls].D[],tree[rs].D[o^]);
}
inline void PushDown(int now,bool o)
{
if (tree[now].l==tree[now].r) return;
if (tree[now].tag[])
tree[ls].D[]+=tree[now].tag[],tree[ls].tag[]+=tree[now].tag[],
tree[rs].D[o]+=tree[now].tag[],tree[rs].tag[o]+=tree[now].tag[],
tree[now].tag[]=;
if (tree[now].tag[])
tree[ls].D[]+=tree[now].tag[],tree[ls].tag[]+=tree[now].tag[],
tree[rs].D[o^]+=tree[now].tag[],tree[rs].tag[o^]+=tree[now].tag[],
tree[now].tag[]=;
}
inline void BuildTree(int now,int l,int r)
{
tree[now].l=l; tree[now].r=r; tree[now].size=r-l+;
if (l==r) {tree[now].D[]=d[l]; tree[now].D[]=INF; return;}
int mid=(l+r)>>;
BuildTree(ls,l,mid); BuildTree(rs,mid+,r);
Update(now,tree[ls].size&);
}
inline void Modify(int now,int L,int R,LL x,bool o)
{
if (L>R) return;
int l=tree[now].l,r=tree[now].r;
PushDown(now,tree[ls].size&);
if (L<=l && R>=r) {tree[now].tag[o]+=x; tree[now].D[o]+=x; return;}
int mid=(l+r)>>;
if (L<=mid) Modify(ls,L,R,x,o);
if (R>mid) Modify(rs,L,R,x,o^(tree[ls].size&));
Update(now,tree[ls].size&);
}
inline LL Query(int now,int L,int R,bool o)
{
if (L>R) return INF;
int l=tree[now].l,r=tree[now].r;
PushDown(now,tree[ls].size&);
if (L<=l && R>=r) return tree[now].D[o];
int mid=(l+r)>>; LL re=INF;
if (L<=mid) re=min(re,Query(ls,L,R,o));
if (R>mid) re=min(re,Query(rs,L,R,o^(tree[ls].size&)));
return re;
}
}
using namespace SegmentTree;
int main()
{
N=read();
for (int i=; i<=N-; i++) a[i]=read();
d[]=a[]; for (int i=; i<=N-; i++) d[i]=a[i]-a[i-],a[i]-=a[i-];
SegmentTree::BuildTree(,,N-);
Q=read();
while (Q--)
{
int opt=read(),L=read(),R=read(),K;
if (opt==)
{
K=read(); SegmentTree::Modify(,L,R,K,L&);
if ((R-L+)&) SegmentTree::Modify(,R+,N-,-K,(R+)&),SegmentTree::Modify(,R+,N-,K,(R+)&);
}
if (opt==)
{
LL x=L>? SegmentTree::Query(,L-,L-,(L-)&):,y=SegmentTree::Query(,R,R,R&);
if ((R-L+)&) y+=x; else y-=x;
if (y!=((R-L+)&) || SegmentTree::Query(,L,R,L&)+x< || SegmentTree::Query(,L,R,(L&)^)-x<) puts("");
else puts("");
}
// puts("=========================");
// for (int i=0; i<=N-1; i++) printf("%I64d %I64d\n",Query(1,i,i,i&1),Query(1,i,i,(i&1)^1));
// puts("=========================");
}
return ;
}

【Codeforces717F】Heroes of Making Magic III 线段树 + 找规律的更多相关文章

  1. W - Doom HDU - 5239 线段树 找取模的规律+求一个很大的数的平方对一个数取模的写法 特别的模数==2^63-2^31

    这个题目一开始感觉还是有点难的,这个模数这么大,根本就不知道怎么写,然后去搜了题解,知道了怎么去求当x很大的时候x的平方对一个数取模怎么样不会爆掉. 然后还顺便发现了一个规律就是当一个数更新一定次数之 ...

  2. Codeforces 717.F Heroes of Making Magic III

    F. Heroes of Making Magic III time limit per test 3 seconds memory limit per test 256 megabytes inpu ...

  3. HDU 5125 magic balls(线段树+DP)

    magic balls Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  4. HDU 5266 pog loves szh III (线段树+在线LCA转RMQ)

    题目地址:HDU 5266 这题用转RMQ求LCA的方法来做的很easy,仅仅须要找到l-r区间内的dfs序最大的和最小的就能够.那么用线段树或者RMQ维护一下区间最值就能够了.然后就是找dfs序最大 ...

  5. SPOJ GSS3 Can you answer these queries III ——线段树

    [题目分析] GSS1的基础上增加修改操作. 同理线段树即可,多写一个函数就好了. [代码] #include <cstdio> #include <cstring> #inc ...

  6. HDU 5266 pog loves szh III 线段树,lca

    Pog and Szh are playing games. Firstly Pog draw a tree on the paper. Here we define 1 as the root of ...

  7. ZOJ 3622 Magic Number 打表找规律

    A - Magic Number Time Limit:2000MS     Memory Limit:32768KB     64bit IO Format:%lld & %llu Subm ...

  8. SPOJ GSS3 Can you answer these queries III[线段树]

    SPOJ - GSS3 Can you answer these queries III Description You are given a sequence A of N (N <= 50 ...

  9. spoj 1557 GSS3 - Can you answer these queries III 线段树

    题目链接 给出n个数, 2种操作, 一种是将第x个数改为y, 第二种是询问区间[x,y]内的最大连续子区间. 开4个数组, 一个是区间和, 一个是区间最大值, 一个是后缀的最大值, 一个是前缀的最大值 ...

随机推荐

  1. Reporting Service 服务启动时报错The service did not respond to the start or control request in a timely fashion

    案例环境: 启动一台数据库服务器(Windows Server 2003)的Reporting Service(SQL Server 2008 R2)服务时,出现如下错误信息: System.Inva ...

  2. C语言--乱写C语言

    C语言的语法太枯燥了 换个写法   #include <stdio.h> #include<stdlib.h> #define end } #define if(x) if ( ...

  3. winform窗体(一)——基本属性

    一.窗体设计界面 二.部分属性 1.基本 设计中的Name:窗体类的类名 AcceptButton:窗口的确定按钮Enter CancelButton:窗口按ESC的取消按钮 2.外观 Backcol ...

  4. MongoDBV3.0.7版本(shard+replica)集群的搭建及验证

    集群的模块介绍: 从MongoDB官方给的集群架构了解,整个集群主要有4个模块:Config Server.mongs. shard.replica set: Config Server:用来存放集群 ...

  5. 致命错误: zlib.h:没有那个文件或目录

    下面这个错误是因为zlib包没有安装,安装后问题即可解决.但有一点请注意安装命令是:sudo apt-get install zlib1g-dev,而非sudo apt-get install zli ...

  6. 为什么我还不推荐内存中OLTP给用户

    嗯,有些人在看玩这篇文章后会恨我,但我还是要说.1个月来我在内存中OLTP这个里领域里做了大量的工作,很多用户都请求使用这个惊艳的新技术.遗憾的是,关于内存中OLTP没有一个是真的令人激动的——看完你 ...

  7. static

    静态数据成员,用关键字static声明,该类的所有对象维护该成员的同一个拷贝(包括该类派生类的对象,即派生类对象与基类对象共享基类的静态数据成员. 1. Static数据成员必须在类外部定义,且正好定 ...

  8. 常用python机器学习库总结

    开始学习Python,之后渐渐成为我学习工作中的第一辅助脚本语言,虽然开发语言是Java,但平时的很多文本数据处理任务都交给了Python.这些年来,接触和使用了很多Python工具包,特别是在文本处 ...

  9. Fiddler进行模拟Post提交数据,总为null解决方式

    Fiddler模拟post提交时总是为空,解决办法 如果是表单提交则要在header加上 ContentType:application/x-www-form-urlencoded 如果是要post提 ...

  10. WPF文章资源库

        MUHAMMAD SHUJAAT SIDDIQI