Submission #164005

# Submission time Handle Problem Language Result Execution time Memory
164005 2019-11-16T20:01:10 Z georgerapeanu Bitaro, who Leaps through Time (JOI19_timeleap) C++11
0 / 100
802 ms 113096 KB
#include <cstdio>
#include <algorithm>
#include <vector>

using namespace std;

const long long NMAX = 3e5;

struct node_t{
    long long breaking_point;
    long long l,r;
    long long real_l,real_r;
    long long cst;

    node_t operator + (const node_t &other)const{
        node_t ans;
        ans.cst = this->cst + other.cst;
        ans.real_l = max(this->real_l,other.real_l);
        ans.real_r = min(this->real_r,other.real_r);
        if(ans.real_l <= ans.real_r){
            ans.breaking_point = ans.real_r;
            ans.cst = 0LL;
            ans.l = ans.real_l;
            ans.r = ans.real_r;
        }
        else{
            if(this->real_l <= this->real_r){
                if(other.real_l <= other.real_r){
                    if(this->r < other.l){
                        ans.cst += 0LL;
                        ans.l = ans.r = other.l;
                        ans.breaking_point = this->r;
                    }
                    else{
                        ans.cst += this->l - other.r;
                        ans.l = ans.r = other.r;
                        ans.breaking_point = this->l;
                    }
                }
                else{
                    ans.l = other.l;ans.r = other.r;
                    if(other.breaking_point > this-> r){
                        ans.breaking_point = this->breaking_point;
                        ans.cst += other.cst;
                    }
                    else if(other.breaking_point >= this->l){
                        ans.breaking_point = other.breaking_point;
                        ans.cst += 0LL;
                    }
                    else{
                        ans.breaking_point = this->l;
                        ans.cst += this->l - other.breaking_point;
                    }
                }
            }
            else{
                if(this->l >= other.breaking_point){
                    ans.cst += this->l - other.breaking_point;
                }
                ans.breaking_point = this->breaking_point;
                if(other.r < this->l){
                    ans.l = ans.r = other.r;
                }
                else if(other.l <= this->l){
                    ans.l = ans.r = this->l;
                }
                else{
                    ans.l = ans.r = other.l;
                }
            }
        }
        return ans;
    }
};

class SegTree{
public:

    long long n;
    node_t aint[NMAX * 4 + 5];

    void build(long long nod,long long st,long long dr,pair<long long,long long> v[]){
        if(st == dr){
            aint[nod].l = aint[nod].real_l = v[st].first;
            aint[nod].r = aint[nod].real_r = v[st].second;
            aint[nod].breaking_point = aint[nod].real_r;
            aint[nod].cst = 0LL;
            return ;
        }

        long long mid = (st + dr) / 2;

        build(nod * 2,st,mid,v);
        build(nod * 2 + 1,mid + 1,dr,v);

        aint[nod] = aint[nod * 2] + aint[nod * 2 + 1];
    }

    void update(long long nod,long long st,long long dr,long long pos,pair<long long,long long> val){
        if(pos < st || pos > dr){
            return ;
        }
        if(st == dr){
            aint[nod].l = aint[nod].real_l = val.first;
            aint[nod].r = aint[nod].real_r = val.second;
            aint[nod].breaking_point = aint[nod].real_r;
            aint[nod].cst = 0LL;
            return ;
        }

        long long mid = (st + dr) / 2;

        update(nod * 2,st,mid,pos,val);
        update(nod * 2 + 1,mid + 1,dr,pos,val);

        aint[nod] = aint[nod * 2] + aint[nod * 2 + 1];
    }

    SegTree(long long n,pair<long long,long long> v[]){
        this->n = n;
        build(1,1,n,v);
    }

    node_t query(long long nod,long long st,long long dr,long long l,long long r){
        if(l <= st && dr <= r){
            return aint[nod];
        }

        long long mid = (st + dr) / 2;

        if(l > mid){
            return query(nod * 2 + 1,mid + 1,dr,l,r);
        }
        else if(r <= mid){
            return query(nod * 2,st,mid,l,r);
        }
        else{
            return query(nod * 2,st,mid,l,r) + query(nod * 2 + 1,mid + 1,dr,l,r);
        }
    }
};

long long n,q;
pair<long long,long long> fst[NMAX + 5];
pair<long long,long long> snd[NMAX + 5];

int main(){

    scanf("%lld %lld",&n,&q);

    for(long long i = 1;i < n;i++){
        scanf("%lld %lld",&fst[i].first,&fst[i].second);
        fst[i].second--;
        snd[n - i] = fst[i];
    }

    for(long long i = 1;i < n;i++){
        fst[i].first -= i;
        fst[i].second -= i;
        snd[i].first -= i;
        snd[i].second -= i;
    }

    SegTree norm(n - 1,fst);
    SegTree rev(n - 1,snd);

    while(q--){
        long long t;
        scanf("%lld",&t);

        if(t == 1){
            long long p,l,r;
            scanf("%lld %lld %lld",&p,&l,&r);
            r--;
            norm.update(1,1,n - 1,p,{l - p,r - p});
            rev.update(1,1,n - 1,n - p,{l - (n - p),r - (n - p)});
        }
        else{
            long long a,b,c,d;
            scanf("%lld %lld %lld %lld",&a,&b,&c,&d);
            if(a == c){
                printf("%lld\n",max(0LL,(long long)b - d));
            }
            else if(a < c){
                b -= a;
                d -= c;
                node_t tmp = norm.query(1,1,n - 1,a,c - 1);
                long long ext_wh = -1;

                if(b > tmp.r){
                    ext_wh = tmp.r;
                }
                else if(b >= tmp.l){
                    ext_wh = b;
                }
                else{
                    ext_wh = tmp.l;
                }

                long long ans = tmp.cst + max(0LL,b - tmp.breaking_point) + max(0LL,ext_wh - d);
                
                printf("%lld\n",ans);
            }
            else{
                a = n + 1 - a;
                c = n + 1 - c;
                b -= a;
                d -= c;
                node_t tmp = rev.query(1,1,n - 1,a,c - 1);
                long long ext_wh = -1;

                if(b > tmp.r){
                    ext_wh = tmp.r;
                }
                else if(b >= tmp.l){
                    ext_wh = b;
                }
                else{
                    ext_wh = tmp.l;
                }
                long long ans = tmp.cst + max(0LL,b - tmp.breaking_point) + max(0LL,ext_wh - d);
                
                printf("%lld\n",ans);
            }
        }
    }

    return 0;
}

Compilation message

timeleap.cpp: In function 'int main()':
timeleap.cpp:149:10: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
     scanf("%lld %lld",&n,&q);
     ~~~~~^~~~~~~~~~~~~~~~~~~
timeleap.cpp:152:14: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
         scanf("%lld %lld",&fst[i].first,&fst[i].second);
         ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
timeleap.cpp:169:14: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
         scanf("%lld",&t);
         ~~~~~^~~~~~~~~~~
timeleap.cpp:173:18: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
             scanf("%lld %lld %lld",&p,&l,&r);
             ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~
timeleap.cpp:180:18: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
             scanf("%lld %lld %lld %lld",&a,&b,&c,&d);
             ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Verdict Execution time Memory Grader output
1 Correct 2 ms 376 KB Output is correct
2 Incorrect 2 ms 376 KB Output isn't correct
3 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Incorrect 802 ms 113096 KB Output isn't correct
2 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 2 ms 376 KB Output is correct
2 Incorrect 2 ms 376 KB Output isn't correct
3 Halted 0 ms 0 KB -