제출 #1358153

#제출 시각아이디문제언어결과실행 시간메모리
1358153KALARRYFish 3 (JOI24_fish3)C++20
100 / 100
332 ms33872 KiB
//chockolateman

#include<bits/stdc++.h>

using namespace std;

const long long INF = 1e15;

int N,Q,p[300005],s[300005],starts[300005];
long long D,a[300005],ans[300005],st[1200005],lazy[1200005];
pair<pair<int,int>,int> queries[300005];

void propagate(int v,int start,int end);

void update(int l,int r,long long val,int v = 1,int start = 1,int end = N)
{
    if(start==l && end==r)
    {
        st[v] += val * (end - start + 1);
        lazy[v] += val;
        return;
    }
    propagate(v,start,end);
    int mid = (start + end)/2;
    if(r <= mid)
        update(l,r,val,2*v,start,mid);
    else if(l > mid)
        update(l,r,val,2*v+1,mid+1,end);
    else
    {
        update(l,mid,val,2*v,start,mid);
        update(mid+1,r,val,2*v+1,mid+1,end);
    }
    st[v] = st[2*v] + st[2*v+1];
}

void propagate(int v,int start,int end)
{
    if(lazy[v])
    {
        int mid = (start + end)/2;
        update(start,mid,lazy[v],2*v,start,mid);
        update(mid+1,end,lazy[v],2*v+1,mid+1,end);
        lazy[v] = 0;
    }
}

long long query(int l,int r,int v = 1,int start = 1,int end = N)
{
    if(start==l && end==r)
        return st[v];
    propagate(v,start,end);
    int mid = (start + end)/2;
    if(r <= mid)
        return query(l,r,2*v,start,mid);
    else if(l > mid)
        return query(l,r,2*v+1,mid+1,end);
    else
        return query(l,mid,2*v,start,mid) + query(mid+1,r,2*v+1,mid+1,end);
}

int find_Sett(int i)
{
    if(p[i]==i)
        return i;
    p[i] = find_Sett(p[i]);
    return p[i];
}

bool is_Same_Sett(int i,int j)
{
    return find_Sett(i) == find_Sett(j);
}

int get_start(int i)
{
    return starts[find_Sett(i)];
}

void union_Sett(int i,int j)
{
    if(is_Same_Sett(i,j))
        return;
    int x = find_Sett(i);
    int y = find_Sett(j);
    if(s[x] < s[y])
        swap(x,y);
    p[y] = x;
    s[x] += s[y];
    starts[x] = min(starts[x],starts[y]);
}

int main()
{
    scanf("%d%lld",&N,&D);
    for(int i = 1 ; i <= N ; i++)
        scanf("%lld",&a[i]);
    for(int i = 1 ; i <= N ; i++)
    {
        p[i] = i;
        s[i] = 1;
        starts[i] = i;
    }
    scanf("%d",&Q);
    for(int l,r,i = 1 ; i <= Q ; i++)
    {
        scanf("%d%d",&l,&r);
        queries[i] = {{r,l},i};
    }
    sort(queries+1,queries+Q+1);
    int pos = 0;
    for(int l,r,indx,i = 1 ; i <= Q ; i++)
    {
        l = queries[i].first.second;
        r = queries[i].first.first;
        indx = queries[i].second;
        //process
        while(pos < r)
        {
            pos++;
            while(get_start(pos) > 1 && a[get_start(pos)] - query(get_start(pos),get_start(pos))*D < a[get_start(pos)-1] - query(get_start(pos)-1,get_start(pos)-1)*D)
            {
                long long lim = a[get_start(pos)] - query(get_start(pos),get_start(pos))*D;
                long long cur_val = a[get_start(pos)-1] - query(get_start(pos)-1,get_start(pos)-1)*D;
                long long targ = (lim/D)*D + cur_val%D;
                if(targ > lim)
                    targ -= D;
                long long red = (cur_val - targ)/D;
                update(get_start(get_start(pos)-1),get_start(pos)-1,red);
                union_Sett(get_start(pos)-1,pos);
            }
        }

        if(a[l] - query(l,l)*D < 0)
            ans[indx] = -1;
        else
            ans[indx] = query(l,r);
    }
    for(int i = 1 ; i <= Q ; i++)
        printf("%lld\n",ans[i]);
    return 0;
}

컴파일 시 표준 에러 (stderr) 메시지

Main.cpp: In function 'int main()':
Main.cpp:95:10: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
   95 |     scanf("%d%lld",&N,&D);
      |     ~~~~~^~~~~~~~~~~~~~~~
Main.cpp:97:14: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
   97 |         scanf("%lld",&a[i]);
      |         ~~~~~^~~~~~~~~~~~~~
Main.cpp:104:10: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  104 |     scanf("%d",&Q);
      |     ~~~~~^~~~~~~~~
Main.cpp:107:14: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  107 |         scanf("%d%d",&l,&r);
      |         ~~~~~^~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...