您的位置:首页 > 理论基础 > 计算机网络

2017武汉大学校赛网络预选赛d题

2017-04-12 18:03 387 查看
Input file: standard input

Output file: standard output

Time limit: 1 second

Memory limit: 512 mebibytes

Every year, the ACM/ICPC team will hold many contests, some of them are training while others are school contests.

In the year of 2017, there are nn contests to be held, and at the beginning of year, we plans the time of each contest.

However, as things are changing. Some other events might affect the time of contest and our team leader wants to know some interesting things about the time of some events.

Input

The first line contains an integer nn. (0 < n \le 10^50

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e5 + 10;
ll inf = 1e18;
ll ans;
int n,q;
struct node{
int l, r;
ll nowMin;//当前区间最小值
ll hisMin;//历史区间最小值
ll add;//延迟标记
}Node[maxn*4];
void pushUp(int i)
{
if(Node[i].l == Node[i].r) return;
int s1 = i<<1;
int s2 = s1 + 1;
Node[i].nowMin = min(Node[s1].nowMin,Node[s2].nowMin);
Node[i].hisMin = min(Node[i].hisMin,Node[i].nowMin);
}
void pushDown(int i)
{
int s1 = i<<1;
int s2 = s1 + 1;
Node[s1].add += Node[i].add;
Node[s2].add += Node[i].add;
Node[i].add = 0;
}
void build(int i,int l,int r)
{
Node[i].l = l;
Node[i].r = r;
Node[i].add = 0;
Node[i].hisMin = inf;
if(l == r)
{
scanf("%lld",&Node[i].nowMin);
Node[i].hisMin = Node[i].nowMin;
return;
}
int f = i;
int mid = (l + r)>>1;
i <<= 1;
build(i,l,mid);
build(i + 1,mid + 1,r);
pushUp(f);
}
void up_down(int i,int l,int r,ll value)
{
Node[i].nowMin += value;
Node[i].hisMin = min(Node[i].hisMin,Node[i].nowMin);
if(l == r) return;
if(value > 0&&Node[i].add < 0)
{
/****************
这一题的巧妙之处就在于这点,当这个区间每个数都要加上一个value时,
如果此时value > 0,并且标记小于0时,要把标记先向下更新,为什么要这样做。
我门们设想一下,此时标记是负数,当它更新下去时,一定可以使下面的每个区间的当前最小值变小,
有可能使历史最小值变小,但是如果不这样更新的话,直接加上value,就会导致这个负数变大,从而使
下面本该变小的没有变小,自己想一下为什么,我这题交了50多遍,心累。
****************/
int s1 = i<<1;
int s2 = s1 + 1;
up_down(s1,Node[s1].l,Node[s1].r,Node[i].add);
up_down(s2,Node[s2].l,Node[s2].r,Node[i].add);
Node[i].add = value;
}
else
{
Node[i].add += value;
}
}
void update(int i,int l,int r,ll value)
{
if(l == Node[i].l&&r == Node[i].r)
{
up_down(i,l,r,value);
return;
}
if(Node[i].add)
{
int s1 = i<<1;
int s2 = s1 + 1;
up_down(s1,Node[s1].l,Node[s1].r,Node[i].add);
up_down(s2,Node[s2].l,Node[s2].r,Node[i].add);
Node[i].add = 0;
}
int f = i;
i <<= 1;
if(r <= Node[i].r) update(i,l,r,value);
else if(l >= Node[i + 1].l) update(i + 1,l,r,value);
else
{
update(i,l,Node[i].r,value);
update(i + 1,Node[i + 1].l,r,value);
}
pushUp(f);
return;
}
void query(int i,int l,int r)
{
if(l == Node[i].l&&r == Node[i].r)
{
ans = min(ans,Node[i].hisMin);
return;
}
if(Node[i].add)
{
int s1 = i<<1;
int s2 = s1 + 1;
up_down(s1,Node[s1].l,Node[s1].r,Node[i].add);
up_down(s2,Node[s2].l,Node[s2].r,Node[i].add);
Node[i].add = 0;
}
i <<= 1;
if(r <= Node[i].r) query(i,l,r);
else if(l >= Node[i + 1].l) query(i + 1,l,r);
else
{
query(i,l,Node[i].r);
query(i + 1,Node[i + 1].l,r);
}
return;
}
int main()
{
scanf("%d",&n);
build(1,1,n);
scanf("%d",&q);
int l,r;
ll t;
for(int i = 1; i <= q; i++)
{
scanf("%d%d%lld",&l,&r,&t);
update(1,l,r,t);
ans = inf;
query(1,l,r);
printf("%lld\n",ans);
}
return 0;
}


4000
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐