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

来源:互联网 发布:明通网络数码科技 编辑:程序博客网 时间:2024/04/28 06:02

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;}
0 0
原创粉丝点击