제출 #683113

#제출 시각아이디문제언어결과실행 시간메모리
683113rainboyPort Facility (JOI17_port_facility)C11
100 / 100
3468 ms252748 KiB
#include <stdio.h>
#include <string.h>

#define N	1000000
#define N_	(1 << 21)	/* N_ = pow2(ceil(log2(N * 2))) */
#define MD	1000000007

int ll[N], rr[N], n;
int stil[2][N_ * 2], stir[2][N_ * 2], n_;

void pul(int c, int i) {
	int l = i << 1, r = l | 1, u, v;

	u = stil[c][l], v = stil[c][r];
	stil[c][i] = v == -1 || u != -1 && ll[u] < ll[v] ? u : v;
	u = stir[c][l], v = stir[c][r];
	stir[c][i] = v == -1 || u != -1 && rr[u] > rr[v] ? u : v;
}

void init() {
	int c, i;

	n_ = 1;
	while (n_ < n * 2)
		n_ <<= 1;
	for (c = 0; c < 2; c++) {
		memset(stil[c], -1, n_ * 2 * sizeof *stil[c]);
		memset(stir[c], -1, n_ * 2 * sizeof *stir[c]);
		for (i = 0; i < n; i++)
			stil[c][n_ + rr[i]] = stir[c][n_ + ll[i]] = i;
		for (i = n_ - 1; i > 0; i--)
			pul(c, i);
	}
}

int query_l(int c, int l, int r) {
	int i_, i;

	i_ = -1;
	for (l += n_, r += n_; l <= r; l >>= 1, r >>= 1) {
		if ((l & 1) == 1) {
			i = stil[c][l++];
			if (i_ == -1 || i != -1 && ll[i_] > ll[i])
				i_ = i;
		}
		if ((r & 1) == 0) {
			i = stil[c][r--];
			if (i_ == -1 || i != -1 && ll[i_] > ll[i])
				i_ = i;
		}
	}
	return i_;
}

int query_r(int c, int l, int r) {
	int i_, i;

	i_ = -1;
	for (l += n_, r += n_; l <= r; l >>= 1, r >>= 1) {
		if ((l & 1) == 1) {
			i = stir[c][l++];
			if (i_ == -1 || i != -1 && rr[i_] < rr[i])
				i_ = i;
		}
		if ((r & 1) == 0) {
			i = stir[c][r--];
			if (i_ == -1 || i != -1 && rr[i_] < rr[i])
				i_ = i;
		}
	}
	return i_;
}

void pull(int c, int i) {
	while (i > 1)
		pul(c, i >>= 1);
}

void remove_(int c, int i) {
	stil[c][n_ + rr[i]] = -1, pull(c, n_ + rr[i]);
	stir[c][n_ + ll[i]] = -1, pull(c, n_ + ll[i]);
}

int uu[2][N];

void dfs(int c, int i, int u) {
	int j;

	uu[c][i] = u;
	remove_(c, i);
	while ((j = query_l(c ^ 1, ll[i], rr[i])) != -1 && ll[j] < ll[i])
		dfs(c ^ 1, j, u);
	while ((j = query_r(c ^ 1, ll[i], rr[i])) != -1 && rr[j] > rr[i])
		dfs(c ^ 1, j, u);
}

long long power(long long a, int k) {
	long long p = 1;

	while (k) {
		if (k & 1)
			p = p * a % MD;
		a = a * a % MD;
		k >>= 1;
	}
	return p;
}

int main() {
	int c, i, k;

	scanf("%d", &n);
	for (i = 0; i < n; i++)
		scanf("%d%d", &ll[i], &rr[i]), ll[i]--, rr[i]--;
	init();
	for (c = 0; c < 2; c++)
		memset(uu[c], -1, n * sizeof *uu[c]);
	k = 0;
	for (c = 0; c < 2; c++)
		for (i = 0; i < n; i++)
			if (uu[c][i] == -1)
				dfs(c, i, k++);
	for (i = 0; i < n; i++)
		if (uu[0][i] == uu[1][i]) {
			printf("0\n");
			return 0;
		}
	printf("%lld\n", power(2, k / 2));
	return 0;
}

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

port_facility.c: In function 'pul':
port_facility.c:15:34: warning: suggest parentheses around '&&' within '||' [-Wparentheses]
   15 |  stil[c][i] = v == -1 || u != -1 && ll[u] < ll[v] ? u : v;
      |                          ~~~~~~~~^~~~~~~~~~~~~~~~
port_facility.c:17:34: warning: suggest parentheses around '&&' within '||' [-Wparentheses]
   17 |  stir[c][i] = v == -1 || u != -1 && rr[u] > rr[v] ? u : v;
      |                          ~~~~~~~~^~~~~~~~~~~~~~~~
port_facility.c: In function 'query_l':
port_facility.c:43:28: warning: suggest parentheses around '&&' within '||' [-Wparentheses]
   43 |    if (i_ == -1 || i != -1 && ll[i_] > ll[i])
      |                    ~~~~~~~~^~~~~~~~~~~~~~~~~
port_facility.c:48:28: warning: suggest parentheses around '&&' within '||' [-Wparentheses]
   48 |    if (i_ == -1 || i != -1 && ll[i_] > ll[i])
      |                    ~~~~~~~~^~~~~~~~~~~~~~~~~
port_facility.c: In function 'query_r':
port_facility.c:62:28: warning: suggest parentheses around '&&' within '||' [-Wparentheses]
   62 |    if (i_ == -1 || i != -1 && rr[i_] < rr[i])
      |                    ~~~~~~~~^~~~~~~~~~~~~~~~~
port_facility.c:67:28: warning: suggest parentheses around '&&' within '||' [-Wparentheses]
   67 |    if (i_ == -1 || i != -1 && rr[i_] < rr[i])
      |                    ~~~~~~~~^~~~~~~~~~~~~~~~~
port_facility.c: In function 'main':
port_facility.c:112:2: warning: ignoring return value of 'scanf' declared with attribute 'warn_unused_result' [-Wunused-result]
  112 |  scanf("%d", &n);
      |  ^~~~~~~~~~~~~~~
port_facility.c:114:3: warning: ignoring return value of 'scanf' declared with attribute 'warn_unused_result' [-Wunused-result]
  114 |   scanf("%d%d", &ll[i], &rr[i]), ll[i]--, rr[i]--;
      |   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...