제출 #111180

#제출 시각아이디문제언어결과실행 시간메모리
111180kig9981Seats (IOI18_seats)C++17
100 / 100
3542 ms78200 KiB
#pragma GCC optimize("O3")
#pragma GCC optimize("Ofast")

#include <bits/stdc++.h>
#include "seats.h"
 
using namespace std;
 
const int SZ=1<<20, dx[]={-1,0,1,0}, dy[]={0,-1,0,1};
vector<pair<int,int>> P;
pair<int,int> tree[2*SZ], lazy[2*SZ];
int N, M, tcnt[2*SZ], idx[1000000];
 
void lazy_propagation(int bit, int s, int e)
{
	tree[bit].first+=lazy[bit].first;
	tree[bit].second+=lazy[bit].second;
	if(s<e) {
		lazy[2*bit].first+=lazy[bit].first;
		lazy[2*bit].second+=lazy[bit].second;
		lazy[2*bit+1].first+=lazy[bit].first;
		lazy[2*bit+1].second+=lazy[bit].second;
	}
	lazy[bit]={0,0};
}
 
void add_tree(int n, pair<int,int> v, int bit=1, int s=0, int e=SZ-1)
{
	int m=(s+e)>>1;
	lazy_propagation(bit,s,e);
	if(e<n) return;
	if(n<=s) {
		tree[bit].first+=v.first;
		tree[bit].second+=v.second;
		if(s<e) {
			lazy[2*bit].first+=v.first;
			lazy[2*bit].second+=v.second;
			lazy[2*bit+1].first+=v.first;
			lazy[2*bit+1].second+=v.second;
		}
		return;
	}
	add_tree(n,v,2*bit,s,m);
	add_tree(n,v,2*bit+1,m+1,e);
	tree[bit]=min(tree[2*bit],tree[2*bit+1]);
	tcnt[bit]=(tree[bit]==tree[2*bit] ? tcnt[2*bit]:0)+(tree[bit]==tree[2*bit+1] ? tcnt[2*bit+1]:0);
}
 
bool valid_coord(int x, int y)
{
	return 0<=x && x<N && 0<=y && y<M;
}
 
int &convert(int x, int y)
{
	return idx[x*M+y];
}
 
pair<int,int> get_corner(int x, int y, int i)
{
	pair<int,int> ret;
	for(int k=0;k<4;k++) {
		if(valid_coord(x+dx[k],y+dy[k]) && valid_coord(x+dx[(k+1)&3],y+dy[(k+1)&3]) && convert(x+dx[k],y+dy[k])<=i && convert(x+dx[(k+1)&3],y+dy[(k+1)&3])<=i && convert(x,y)>i) {
			ret.second++;
		}
		else if((!valid_coord(x+dx[k],y+dy[k]) || convert(x+dx[k],y+dy[k])>i) && (!valid_coord(x+dx[(k+1)&3],y+dy[(k+1)&3]) || convert(x+dx[(k+1)&3],y+dy[(k+1)&3])>i) && convert(x,y)<=i) {
			ret.first++;
		}
	}
	return ret;
}
 
pair<int,int> get_diff(int i)
{
	pair<int,int> ret, temp;
	int x=P[i].first, y=P[i].second;
	temp=get_corner(x,y,i); ret.first+=temp.first; ret.second+=temp.second;
	temp=get_corner(x,y,i-1); ret.first-=temp.first; ret.second-=temp.second;
	for(int k=0;k<4;k++) if(valid_coord(x+dx[k],y+dy[k])) {
		temp=get_corner(x+dx[k],y+dy[k],i); ret.first+=temp.first; ret.second+=temp.second;
		temp=get_corner(x+dx[k],y+dy[k],i-1); ret.first-=temp.first; ret.second-=temp.second;
	}
	return ret;
}
 
void give_initial_chart(int H, int W, vector<int> R, vector<int> C)
{
	P.resize(H*W);
	N=H; M=W;
	for(int i=0;i<H*W;i++) {
		P[i]={R[i],C[i]};
		convert(R[i],C[i])=i;
		tcnt[SZ+i]=1;
	}
	tree[SZ]=get_diff(0);
	for(int i=1;i<H*W;i++) {
		tree[SZ+i]=get_diff(i);
		tree[SZ+i].first+=tree[SZ+i-1].first;
		tree[SZ+i].second+=tree[SZ+i-1].second;
	}
	for(int i=H*W;i<SZ;i++) tree[SZ+i]=make_pair(0x1fffffff,0x1fffffff);
	for(int i=SZ-1;i;i--) {
		tree[i]=min(tree[2*i],tree[2*i+1]);
		tcnt[i]=(tree[i]==tree[2*i] ? tcnt[2*i]:0)+(tree[i]==tree[2*i+1] ? tcnt[2*i+1]:0);
	}
}
 
int swap_seats(int a, int b)
{
	pair<int,int> temp;
	int x1=P[a].first, y1=P[a].second, x2=P[b].first, y2=P[b].second;
	set<int> C;
	for(int dx=-1;dx<2;dx++) for(int dy=-1;dy<2;dy++) {
		if(valid_coord(x1+dx,y1+dy)) C.insert(convert(x1+dx,y1+dy));
		if(valid_coord(x2+dx,y2+dy)) C.insert(convert(x2+dx,y2+dy));
	}
	for(auto c: C) {
		temp=get_diff(c); temp.first*=-1; temp.second*=-1;
		add_tree(c,temp);
	}
	swap(P[a],P[b]);
	swap(convert(P[a].first,P[a].second),convert(P[b].first,P[b].second));
	for(auto c: C) add_tree(c,get_diff(c));
	return tcnt[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...