제출 #458462

#제출 시각아이디문제언어결과실행 시간메모리
458462leinad2식물 비교 (IOI20_plants)C++17
100 / 100
2454 ms117532 KiB
#include "plants.h"
#include<bits/stdc++.h>
using namespace std;
int K, i, j, N, R[200010], X[200010], lazy[800010], A[200010], B[200010], sparse1[200010][20], sparse2[200010][20];
long long sparse3[200010][20], sparse4[200010][20];
struct st
{
    int x, y;
    const bool operator<(st a)const
    {
        if(x==a.x)return y<a.y;
        return x>a.x;
    }
};
set<st>s;
struct node
{
    int x, y;
}seg[800010];
node merge(node a, node b)
{
    if(a.x<b.x)return a;
    if(a.x>b.x)return b;
    return {a.x, min(a.y, b.y)};
}
void busy(int id)
{
    seg[id*2].x+=lazy[id];
    seg[id*2+1].x+=lazy[id];
    lazy[id*2]+=lazy[id];
    lazy[id*2+1]+=lazy[id];
    lazy[id]=0;
}
void init(int id, int s, int e)
{
    if(s==e)
    {
        seg[id].x=R[s];
        seg[id].y=s;
        return;
    }
    int m=s+e>>1;
    init(id*2, s, m);init(id*2+1, m+1, e);
    seg[id]=merge(seg[id*2], seg[id*2+1]);
}
void update(int id, int s, int e, int l, int r, int v)
{
    if(e<l||r<s)return;
    if(l<=s&&e<=r)
    {
        lazy[id]+=v;
        seg[id].x+=v;
        return;
    }
    busy(id);int m=s+e>>1;
    update(id*2, s, m, l, r, v);update(id*2+1, m+1, e, l, r, v);
    seg[id]=merge(seg[id*2], seg[id*2+1]);
}
node get(int id, int s, int e, int l, int r)
{
    if(e<l||r<s)return {(int)1e9, 0};
    if(l<=s&&e<=r)return seg[id];
    busy(id);int m=s+e>>1;
    return merge(get(id*2, s, m, l, r), get(id*2+1, m+1, e, l, r));
}
int f(int a)
{
    a%=N;
    if(a<=0)a+=N;
    return a;
}
void init(int k, vector<int>r)
{
    K=k;N=r.size();for(i=0;i++<N;)X[i]=-1;
    for(i=0;i++<N;)R[i]=r[i-1];
    init(1, 1, N);
    vector<int>v;
    for(i=0;i++<N;)
    {
        if(R[i]==0)
        {
            if(i>=K)
            {
                node a=get(1, 1, N, i-K+1, i-1);
                if(a.x)v.push_back(i);
            }
            else
            {
                node a=merge(get(1, 1, N, 1, i-1), get(1, 1, N, N-K+i+1, N));
                if(a.x)v.push_back(i);
            }
        }
    }
    int group=0;
    while(v.size())
    {
        vector<int>V;
        for(auto i:v)
        {
            if(i>=K)update(1, 1, N, i-K+1, i-1, -1);
            else update(1, 1, N, 1, i-1, -1),update(1, 1, N, N-k+i+1, N, -1);
            X[i]=group;update(1, 1, N, i, i, 1e9);
        }
        for(auto i:v)
        {
            if(i>=K)
            {
                node a=get(1, 1, N, i-K+1, i-1);
                if(a.x==0)V.push_back(a.y);
            }
            else
            {
                node a=get(1, 1, N, 1, i-1);
                node b=get(1, 1, N, N-k+i+1, N);
                if(b.x==0)V.push_back(b.y);
                else if(a.x==0)V.push_back(a.y);
            }
            if(i<=N-K+1)
            {
                node a=get(1, 1, N, i+1, i+K-1);
                if(a.x==0)V.push_back(a.y);
            }
            else
            {
                node a=get(1, 1, N, i+1, N);
                node b=get(1, 1, N, 1, i+K-1-N);
                if(a.x==0)V.push_back(a.y);
                else if(b.x==0)V.push_back(b.y);
            }
        }
        sort(V.begin(), V.end());
        v.clear();
        for(auto i:V)
        {
            node a;
            if(i>=K)a=get(1, 1, N, i-K+1, i-1);
            else a=merge(get(1, 1, N, 1, i-1), get(1, 1, N, i-K+1+N, N));
            if(a.x==0)continue;
            if(!v.size()||v.back()!=i)v.push_back(i);
        }
        group++;
    }
    for(i=0;i++<N;)X[i]=N-X[i];
    for(j=-K+2;j<=0;j++)s.insert({X[f(j)], j});
    for(i=0;i++<N;)
    {
        if((*s.rbegin()).x>=X[i])A[i]=i;
        else A[i]=f((*s.lower_bound({X[i]-1, (int)-1e9})).y);
        s.erase({X[f(i-K+1)], i-K+1});
        s.insert({X[i], i});
    }
    s.clear();
    for(i=1;i<=N/2;i++)swap(X[i], X[N+1-i]);
    for(j=-K+2;j<=0;j++)s.insert({X[f(j)], j});
    for(i=0;i++<N;)
    {
        if((*s.rbegin()).x>=X[i])B[i]=i;
        else B[i]=f((*s.lower_bound({X[i]-1, (int)-1e9})).y);
        s.erase({X[f(i-K+1)], i-K+1});
        s.insert({X[i], i});
    }
    for(i=1;i<=N/2;i++)swap(X[i], X[N+1-i]);
    for(i=0;i++<N;)B[i]=N+1-B[i];
    for(i=1;i<=N/2;i++)swap(B[i], B[N+1-i]);
    for(i=0;i++<N;)sparse1[i][0]=A[i],sparse2[i][0]=B[i];
    for(i=0;i++<N;)sparse3[i][0]=f(i-A[i])%N,sparse4[i][0]=f(B[i]-i)%N;
    for(j=1;j<20;j++)
    {
        for(i=0;i++<N;)
        {
            sparse1[i][j]=sparse1[sparse1[i][j-1]][j-1];
            sparse2[i][j]=sparse2[sparse2[i][j-1]][j-1];
            sparse3[i][j]=sparse3[sparse1[i][j-1]][j-1]+sparse3[i][j-1];
            sparse4[i][j]=sparse4[sparse2[i][j-1]][j-1]+sparse4[i][j-1];
        }
    }
	return;
}
int compare_plants(int x, int y)
{
    if(X[x+1]<X[y+1])return -compare_plants(y, x);
    x++;y++;
    int a=x, b=x;long long dist=0, dist2=0;
    for(j=19;j>=0;j--)
    {
        if(X[sparse1[a][j]]>=X[y])
        {
            dist+=sparse3[a][j];
            a=sparse1[a][j];
        }
        if(X[sparse2[b][j]]>=X[y])
        {
            dist2+=sparse4[b][j];
            b=sparse2[b][j];
        }
    }
    long long p=x-dist, q=x+dist2;
    if((p<=y-N&&y-N<=q)||(p<=y&&y<=q)||(p<=y+N&&y+N<=q))return 1;
    return 0;
}

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

plants.cpp: In function 'void init(int, int, int)':
plants.cpp:42:12: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   42 |     int m=s+e>>1;
      |           ~^~
plants.cpp: In function 'void update(int, int, int, int, int, int)':
plants.cpp:55:21: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   55 |     busy(id);int m=s+e>>1;
      |                    ~^~
plants.cpp: In function 'node get(int, int, int, int, int)':
plants.cpp:63:21: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   63 |     busy(id);int m=s+e>>1;
      |                    ~^~
#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...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...