제출 #908744

#제출 시각아이디문제언어결과실행 시간메모리
908744JakobZorz자리 배치 (IOI18_seats)C++17
100 / 100
3616 ms225356 KiB
#include"seats.h"
#include<iostream>
#include<algorithm>
using namespace std;

const int TREE_SIZE=1<<20;

int w,h;
vector<int>x,y;
vector<vector<int>>mat;
vector<pair<int,int>>tree[2*TREE_SIZE];
int arr0[TREE_SIZE];
int lazy[2*TREE_SIZE];

int get_mat(int x,int y){
    if(x<0||x>=w||y<0||y>=h)
        return w*h;
    return mat[x][y];
}

void push_lazy(int node){
    if(lazy[node]!=0){
        if(node<TREE_SIZE){
            lazy[2*node]+=lazy[node];
            lazy[2*node+1]+=lazy[node];
        }
        for(auto&i:tree[node])
            i.first+=lazy[node];
        lazy[node]=0;
    }
}

void update_node(int node){
    if(node<TREE_SIZE){
        tree[node].clear();
        int i1=0,i2=0;
        int s1=tree[2*node].size();
        int s2=tree[2*node+1].size();
        while(tree[node].size()<4&&(i1<s1||i2<s2)){
            if(i2==s2){
                tree[node].push_back(tree[2*node][i1]);
                i1++;
                continue;
            }
            
            if(i1==s1){
                tree[node].push_back(tree[2*node+1][i2]);
                i2++;
                continue;
            }
            
            if(tree[2*node][i1].first==tree[2*node+1][i2].first){
                tree[node].emplace_back(tree[2*node][i1].first,tree[2*node][i1].second+tree[2*node+1][i2].second);
                i1++;
                i2++;
                continue;
            }
            
            if(tree[2*node][i1].first<tree[2*node+1][i2].first){
                tree[node].push_back(tree[2*node][i1]);
                i1++;
            }else{
                tree[node].push_back(tree[2*node+1][i2]);
                i2++;
            }
        }
    }
}

void update(int node,int rl,int rr,int l,int r,int v){
    push_lazy(node);
    if(r<=rl||rr<=l)
        return;
    if(l<=rl&&rr<=r){
        lazy[node]+=v;
        push_lazy(node);
        return;
    }
    
    int mid=(rl+rr)/2;
    update(2*node,rl,mid,l,r,v);
    update(2*node+1,mid,rr,l,r,v);
    update_node(node);
}

void update(int l,int r,int v){
    update(1,0,TREE_SIZE,l,r,v);
}

void upd_sq(int x,int y,int mul){ // 1 for adding and -1 for removing
    vector<int>vals={get_mat(x,y),get_mat(x+1,y),get_mat(x,y+1),get_mat(x+1,y+1)};
    sort(vals.begin(),vals.end());
    
    update(vals[0],vals[1],mul);
    update(vals[2],vals[3],mul);
}

void upd_sq2(int x,int y){
    vector<int>vals={get_mat(x,y),get_mat(x+1,y),get_mat(x,y+1),get_mat(x+1,y+1)};
    sort(vals.begin(),vals.end());
    
    arr0[vals[0]]++;
    arr0[vals[1]]--;
    arr0[vals[2]]++;
    arr0[vals[3]]--;
}

void give_initial_chart(int H,int W,vector<int>R,vector<int>C){
    x=C;
    y=R;
    h=H;
    w=W;
    mat=vector<vector<int>>(w,vector<int>(h));
    for(int i=0;i<w*h;i++)
        mat[x[i]][y[i]]=i;
    
    for(int x=-1;x<w;x++)
        for(int y=-1;y<h;y++)
            upd_sq2(x,y);
    
    int cv=0;
    for(int i=TREE_SIZE;i<2*TREE_SIZE;i++){
        cv+=arr0[i-TREE_SIZE];
        tree[i]={{cv,1}};
    }
    for(int i=TREE_SIZE-1;i>0;i--)
        update_node(i);
}

int swap_seats(int a,int b){
    upd_sq(x[a]-1,y[a]-1,-1);
    upd_sq(x[a]-1,y[a],-1);
    upd_sq(x[a],y[a]-1,-1);
    upd_sq(x[a],y[a],-1);
    upd_sq(x[b]-1,y[b]-1,-1);
    upd_sq(x[b]-1,y[b],-1);
    upd_sq(x[b],y[b]-1,-1);
    upd_sq(x[b],y[b],-1);
    swap(mat[x[a]][y[a]],mat[x[b]][y[b]]);
    swap(x[a],x[b]);
    swap(y[a],y[b]);
    upd_sq(x[a]-1,y[a]-1,1);
    upd_sq(x[a]-1,y[a],1);
    upd_sq(x[a],y[a]-1,1);
    upd_sq(x[a],y[a],1);
    upd_sq(x[b]-1,y[b]-1,1);
    upd_sq(x[b]-1,y[b],1);
    upd_sq(x[b],y[b]-1,1);
    upd_sq(x[b],y[b],1);
    
    int res=0;
    for(auto i:tree[1]){
        if(i.first==4)
            res=i.second;
    }
    return res;
}
#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...