답안 #304167

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
304167 2020-09-21T03:53:36 Z daniel920712 식물 비교 (IOI20_plants) C++14
0 / 100
51 ms 95864 KB
#include "plants.h"
#include <stdio.h>
#include <vector>
#include <utility>
#include <set>
using namespace std;
vector < int > all;
vector < int > ttt;
vector < int > Next[200005];
vector < pair < int , int > > con[200005];
int N,tt=0;
bool use[2000005]={0};
int Con[200005];
int what[200005];
int now=1;
struct A
{
    int l,r;
    int nxl,nxr;
    int small1,small2,small3;
    int big2;
    int add1,add2;
    int ok=0;
}Node[2000005];
void build(int l,int r,int here)
{
    Node[here].l=l;
    Node[here].r=r;
    Node[here].add1=0;
    Node[here].add2=0;
    Node[here].small1=0;
    Node[here].small3=1e9;
    Node[here].ok=0;
    if(l==r)
    {
        Node[here].small2=all[l];
        Node[here].big2=all[l];
        return ;
    }
    Node[here].nxl=now++;
    Node[here].nxr=now++;
    build(l,(l+r)/2,Node[here].nxl);
    build((l+r)/2+1,r,Node[here].nxr);
    Node[here].small2=min(Node[Node[here].nxl].small2,Node[Node[here].nxr].small2);
    Node[here].small3=min(Node[Node[here].nxl].small3,Node[Node[here].nxr].small3);
    Node[here].small1=min(Node[Node[here].nxl].small1,Node[Node[here].nxr].small1);
    Node[here].big2=max(Node[Node[here].nxl].big2,Node[Node[here].nxr].big2);

}
void UPD(int here)
{
    Node[Node[here].nxl].add1+=Node[here].add1;
    Node[Node[here].nxl].small1+=Node[here].add1;
    Node[Node[here].nxr].add1+=Node[here].add1;
    Node[Node[here].nxr].small1+=Node[here].add1;
    Node[Node[here].nxr].small3+=Node[here].add1;
    Node[Node[here].nxl].small3+=Node[here].add1;
    Node[here].add1=0;
    Node[Node[here].nxl].add2+=Node[here].add2;
    Node[Node[here].nxl].small2+=Node[here].add2;
    Node[Node[here].nxr].add2+=Node[here].add2;
    Node[Node[here].nxr].small2+=Node[here].add2;
    Node[Node[here].nxl].big2+=Node[here].add2;
    Node[Node[here].nxr].big2+=Node[here].add2;
    Node[here].add2=0;
}
void cha1(int l,int r,int con,int here)
{
    if(l>r) return ;
    if(l==Node[here].l&&r==Node[here].r)
    {
        Node[here].add1+=con;
        Node[here].small1+=con;
        Node[here].small3+=con;
        return;
    }
    UPD(here);
    if(r<=(Node[here].l+Node[here].r)/2) cha1(l,r,con,Node[here].nxl);
    else if(l>(Node[here].l+Node[here].r)/2) cha1(l,r,con,Node[here].nxr);
    else
    {
        cha1(l,(Node[here].l+Node[here].r)/2,con,Node[here].nxl);
        cha1((Node[here].l+Node[here].r)/2+1,r,con,Node[here].nxr);
    }
    Node[here].big2=max(Node[Node[here].nxl].big2,Node[Node[here].nxr].big2);
    Node[here].small2=min(Node[Node[here].nxl].small2,Node[Node[here].nxr].small2);
    Node[here].small1=min(Node[Node[here].nxl].small1,Node[Node[here].nxr].small1);
    Node[here].small3=min(Node[Node[here].nxl].small3,Node[Node[here].nxr].small3);
    Node[here].ok=Node[Node[here].nxl].ok||Node[Node[here].nxr].ok;
}

void cha2(int l,int r,int con,int here)
{
    if(l>r) return ;
    if(l==Node[here].l&&r==Node[here].r)
    {
        Node[here].add2+=con;
        Node[here].small2+=con;
        Node[here].big2+=con;
        if(l==r&&con==1000000000) Node[here].small3=Node[here].small1;
        return;
    }
    UPD(here);
    if(r<=(Node[here].l+Node[here].r)/2) cha2(l,r,con,Node[here].nxl);
    else if(l>(Node[here].l+Node[here].r)/2) cha2(l,r,con,Node[here].nxr);
    else
    {
        cha2(l,(Node[here].l+Node[here].r)/2,con,Node[here].nxl);
        cha2((Node[here].l+Node[here].r)/2+1,r,con,Node[here].nxr);
    }
    Node[here].big2=max(Node[Node[here].nxl].big2,Node[Node[here].nxr].big2);
    Node[here].small2=min(Node[Node[here].nxl].small2,Node[Node[here].nxr].small2);
    Node[here].small1=min(Node[Node[here].nxl].small1,Node[Node[here].nxr].small1);
    Node[here].small3=min(Node[Node[here].nxl].small3,Node[Node[here].nxr].small3);
    Node[here].ok=Node[Node[here].nxl].ok||Node[Node[here].nxr].ok;
}
int Find1(int where,int here)
{
    if(Node[here].l==where&&Node[here].r==where) return Node[here].small1;
    UPD(here);
    if(where<=(Node[here].l+Node[here].r)/2) return Find1(where,Node[here].nxl);
    else return Find1(where,Node[here].nxr);
}
int Find2(int where,int here)
{
    if(Node[here].l==where&&Node[here].r==where) return Node[here].small2;
    UPD(here);
    if(where<=(Node[here].l+Node[here].r)/2) return Find2(where,Node[here].nxl);
    else return Find2(where,Node[here].nxr);
}

void New(int here)
{
    if(Node[here].l==Node[here].r)
    {
        ttt.push_back(Node[here].l);
        return;
    }
    UPD(here);
    if(Node[Node[here].nxl].small2==0) New(Node[here].nxl);
    if(Node[Node[here].nxr].small2==0) New(Node[here].nxr);

}
int New2(int here)
{
    //printf("%d %d %d %d %d %d\n",Node[here].l,Node[here].r,Node[Node[here].nxl].big2,Node[Node[here].nxl].small1,Node[Node[here].nxr].big2,Node[Node[here].nxr].small1);
    if(Node[here].l==Node[here].r) return Node[here].l;
    UPD(here);
    if(Node[Node[here].nxl].small3==0&&Node[Node[here].nxl].big2>N) return New2(Node[here].nxl);
    else return New2(Node[here].nxr);

}
bool F(int a,int b)
{
    if(a==b) return 1;
    if(use[a]) return 0;
    use[a]=1;
    for(auto i:Next[a]) if(F(i,b)) return 1;
    return 0;
}
void init(int k,vector<int> r)
{
    int a=0,b=0,i,j,ok=0,l,t,t2,x,ll,rr;
    all=r;
    N=r.size();
    if(k==2)
    {
        tt=1;
        for(i=0;i<N;i++)
        {
            if(r[(i+N-1)%N]!=r[i])
            {
                b=0;
                a++;
                con[i].push_back(make_pair(a,0));
                for(j=(i+1)%N;r[(j+N-1)%N]==r[i];j=(j+1)%N)
                {
                    if(j==N-1) ok=1;
                    if(r[i]==0) b--;
                    else b++;
                    con[j].push_back(make_pair(a,b));
                }
            }
        }
    }
    else if(N<=300)
    {
        tt=2;
        for(i=0;i<N;i++)
        {
            if(r[i]==0)
            {
                for(j=1;j<k;j++)
                {
                    t=(i+j)%N;
                    Con[t]++;
                }
            }
        }
        for(i=0;i<N;i++)
        {
            for(j=0;j<N;j++)
            {
                if(use[j]==0&&Con[j]==0&&r[j]==0)
                {
                    x=j;
                    break;
                }
            }
            use[x]=1;
            for(j=1;j<k;j++)
            {
                t=(x+j)%N;
                Con[t]--;
                if(!use[t]) Next[t].push_back(x);
            }
            for(j=1;j<k;j++)
            {
                t=(x-j+2*N)%N;
                r[t]--;
                if(use[t]) Next[x].push_back(t);
                if(r[t]==0)
                {
                    for(l=1;l<k;l++)
                    {
                        t2=(t+l)%N;
                        Con[t2]++;
                    }
                }
            }
            //for(j=0;j<N;j++) if(!use[j]) printf("%d %d %d\n",j,r[j],Con[j]);

        }
    }
    else
    {
        build(0,N-1,0);
        ttt.clear();
        New(0);
        for(auto t:ttt)
        {
            cha2(t,t,1e9,0);
            t2=(t+k-1)%N;
            if(t2>=t) cha1(t+1,t2,1,0);
            else
            {
                cha1(t+1,N-1,1,0);
                cha1(0,t2,1,0);
            }
        }
        for(i=0;i<N;i++)
        {
            x=New2(0);
            cha1(x,x,1e9,0);
            what[x]=i;
            t=(x+k-1)%N;
            if(t>=x) cha1(x+1,t,-1,0);
            else
            {
                cha1(x+1,N-1,-1,0);
                cha1(0,t,-1,0);
            }
            ll=(x-(k-1)+N)%N;
            rr=(x-1+N)%N;
            if(rr>=ll) cha2(ll,rr,-1,0);
            else
            {
                cha2(ll,N-1,-1,0);
                cha2(0,rr,-1,0);
            }
            ttt.clear();
            New(0);
            for(auto t:ttt)
            {
                cha2(t,t,1e9,0);
                t2=(t+k-1)%N;
                if(t2>=t) cha1(t+1,t2,1,0);
                else
                {
                    cha1(t+1,N-1,1,0);
                    cha1(0,t2,1,0);
                }
            }

        }
    }
	return;
}

int compare_plants(int x, int y)
{
    int i;
    if(tt==1)
    {
        for(auto i:con[x])
        {
            for(auto j:con[y])
            {
                if(i.first==j.first)
                {
                    if(i.second<j.second) return -1;
                    return 1;
                }
            }
        }

    }
    else if(tt==2)
    {
        for(i=0;i<N;i++) use[i]=0;
        if(F(x,y)) return 1;
        for(i=0;i<N;i++) use[i]=0;
        if(F(y,x)) return -1;
        return 0;
    }
    else
    {
        if(what[x]<what[y]) return 1;
        else return -1;
    }
}

Compilation message

plants.cpp: In function 'void init(int, std::vector<int>)':
plants.cpp:163:21: warning: variable 'ok' set but not used [-Wunused-but-set-variable]
  163 |     int a=0,b=0,i,j,ok=0,l,t,t2,x,ll,rr;
      |                     ^~
plants.cpp: In function 'int compare_plants(int, int)':
plants.cpp:321:1: warning: control reaches end of non-void function [-Wreturn-type]
  321 | }
      | ^
# 결과 실행 시간 메모리 Grader output
1 Correct 47 ms 95736 KB Output is correct
2 Correct 47 ms 95768 KB Output is correct
3 Correct 47 ms 95864 KB Output is correct
4 Incorrect 48 ms 95736 KB Output isn't correct
5 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 46 ms 95736 KB Output is correct
2 Correct 47 ms 95736 KB Output is correct
3 Incorrect 46 ms 95808 KB Output isn't correct
4 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 46 ms 95736 KB Output is correct
2 Correct 47 ms 95736 KB Output is correct
3 Incorrect 46 ms 95808 KB Output isn't correct
4 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 48 ms 95736 KB Output is correct
2 Incorrect 46 ms 95864 KB Output isn't correct
3 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 47 ms 95740 KB Output is correct
2 Correct 46 ms 95780 KB Output is correct
3 Incorrect 51 ms 95736 KB Output isn't correct
4 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 47 ms 95736 KB Output is correct
2 Correct 47 ms 95736 KB Output is correct
3 Incorrect 48 ms 95736 KB Output isn't correct
4 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 47 ms 95736 KB Output is correct
2 Correct 47 ms 95768 KB Output is correct
3 Correct 47 ms 95864 KB Output is correct
4 Incorrect 48 ms 95736 KB Output isn't correct
5 Halted 0 ms 0 KB -