답안 #333392

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
333392 2020-12-05T19:54:33 Z arnold518 절취선 (JOI14_ho_t5) C++14
100 / 100
2786 ms 199424 KB
#pragma GCC optimize ("O3")
#pragma GCC optimize ("Ofast")
#pragma GCC optimize ("unroll-loops")
 
#include <bits/stdc++.h>
using namespace std;
 
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
 
const int MAXN = 2e5;
const int MAXV = 3.6e6;
 
struct Line
{
	int x1, y1, x2, y2, p;
};
 
int W, H, N, M, SX, SY;
Line A[MAXN/2+10], B[MAXN/2+10];
 
vector<int> xcomp, ycomp;
 
ll V, E, C=1;
 
struct BIT
{
	int tree[MAXN+10];
	void update(int i, int x) { for(; i<=SY; i+=(i&-i)) tree[i]+=x; }
	int query(int i) { int ret=0; for(; i>0; i-=(i&-i)) ret+=tree[i]; return ret; }
	int query(int l, int r) { return query(r)-query(l-1); }
}bit;
 
int LC[MAXV+10], RC[MAXV+10];
int ncnt;

int newNode()
{
	if(ncnt+1==MAXV) while(1);
	return ++ncnt;
}
 
vector<pii> adj;
vector<int> radj[MAXN+10];
 
void addEdge(int u, int v)
{
	//printf("%d %d\n", u, v);
	if(u==-1 || v==-1) return;
	adj.push_back({u, v});
}
 
int update(int node, int tl, int tr, int p, int k)
{
	if(p<tl || tr<p) return node;
	if(tr-tl+1<=1)
	{
		if(k>0) return k;
		return -1;
	}
	int ret=newNode();
	int mid=tl+tr>>1;
	LC[ret]=update(LC[node], tl, mid, p, k);
	RC[ret]=update(RC[node], mid+1, tr, p, k);
	addEdge(LC[ret], ret);
	addEdge(RC[ret], ret);
	return ret;
}
 
void query(int node, int tl, int tr, int l, int r, int k)
{
	if(r<tl || tr<l) return;
	if(l<=tl && tr<=r)
	{
		addEdge(node, k);
		radj[k].push_back(node);
		return;
	}
	int mid=tl+tr>>1;
	query(LC[node], tl, mid, l, r, k);
	query(RC[node], mid+1, tr, l, r, k);
}
 
bool vis[MAXV+10];
vector<int> S;
void dfs(int now)
{
	vis[now]=true;
	for(auto it=lower_bound(adj.begin(), adj.end(), pii(now, 0)); it<adj.end() && it->first==now; it++)
	{
		int nxt=it->second;
		if(vis[nxt]) continue;
		dfs(nxt);
	}
	S.push_back(now);
}
 
int scc[MAXV+10], scnt;
void dfs2(int now)
{
	scc[now]=scnt;
	if(now>N+M)
	{
		int nxt=LC[now];
		if(nxt!=-1 && !scc[nxt]) dfs2(nxt);
		nxt=RC[now];
		if(nxt!=-1 && !scc[nxt]) dfs2(nxt);
	}
	else
	{
		for(int nxt : radj[now])
		{
			if(scc[nxt]) continue;
			dfs2(nxt);
		}
	}
}
 
int main()
{
	int t;
	scanf("%d%d%d", &W, &H, &t);
	for(int i=1; i<=t; i++)
	{
		Line p;
		scanf("%d%d%d%d", &p.x1, &p.y1, &p.x2, &p.y2);
		xcomp.push_back(p.x1);
		xcomp.push_back(p.x2);
		ycomp.push_back(p.y1);
		ycomp.push_back(p.y2);
		if(p.x1==p.x2) B[++M]=p;
		else A[++N]=p;
	}
 
	xcomp.push_back(0);
	ycomp.push_back(0);
	xcomp.push_back(W);
	ycomp.push_back(H);
 
	A[++N]={0, 0, W, 0};
	A[++N]={0, H, W, H};
	B[++M]={0, 0, 0, H};
	B[++M]={W, 0, W, H};
 
	sort(xcomp.begin(), xcomp.end());
	xcomp.erase(unique(xcomp.begin(), xcomp.end()), xcomp.end());
	sort(ycomp.begin(), ycomp.end());
	ycomp.erase(unique(ycomp.begin(), ycomp.end()), ycomp.end());
 
	SX=xcomp.size(); SY=ycomp.size();
 
	for(int i=1; i<=N; i++)
	{
		A[i].x1=lower_bound(xcomp.begin(), xcomp.end(), A[i].x1)-xcomp.begin()+1;
		A[i].x2=lower_bound(xcomp.begin(), xcomp.end(), A[i].x2)-xcomp.begin()+1;
		A[i].y1=lower_bound(ycomp.begin(), ycomp.end(), A[i].y1)-ycomp.begin()+1;
		A[i].y2=lower_bound(ycomp.begin(), ycomp.end(), A[i].y2)-ycomp.begin()+1;
		A[i].p=newNode();
	}
	for(int i=1; i<=M; i++)
	{
		B[i].x1=lower_bound(xcomp.begin(), xcomp.end(), B[i].x1)-xcomp.begin()+1;
		B[i].x2=lower_bound(xcomp.begin(), xcomp.end(), B[i].x2)-xcomp.begin()+1;
		B[i].y1=lower_bound(ycomp.begin(), ycomp.end(), B[i].y1)-ycomp.begin()+1;
		B[i].y2=lower_bound(ycomp.begin(), ycomp.end(), B[i].y2)-ycomp.begin()+1;
		B[i].p=newNode();
	}
	xcomp.clear(); xcomp.shrink_to_fit();
	ycomp.clear(); ycomp.shrink_to_fit();
 
	for(int i=1; i<=N; i++)
	{
		E+=A[i].x2-A[i].x1;
		V+=A[i].x2-A[i].x1+1;
	}
	for(int i=1; i<=M; i++)
	{
		E+=B[i].y2-B[i].y1;
		V+=B[i].y2-B[i].y1+1;
	}
 
	sort(B+1, B+M+1, [&](const Line &p, const Line &q)
	{
		return p.x1<q.x1;
	});
 
	vector<pair<pll, int>> VV;
	for(int i=1; i<=N; i++)
	{
		VV.push_back({{A[i].x1, A[i].y1}, 1});
		VV.push_back({{A[i].x2+1, A[i].y1}, -1});
	}
	sort(VV.begin(), VV.end());
 
	for(int i=1, j=0; i<=M; i++)
	{
		for(; j<VV.size() && VV[j].first.first<=B[i].x1; j++)
		{
			bit.update(VV[j].first.second, VV[j].second);
		}
		V-=bit.query(B[i].y1, B[i].y2);
	}
 
	int root;
 
	VV.clear(); VV.shrink_to_fit();
	for(int i=1; i<=N; i++)
	{
		VV.push_back({{A[i].x1, A[i].y1}, A[i].p});
		VV.push_back({{A[i].x2+1, A[i].y1}, 0});
	}
	sort(VV.begin(), VV.end());
 
	root=newNode();
	//makeTree(root, 1, SY);
	for(int i=1, j=0; i<=M; i++)
	{
		for(; j<VV.size() && VV[j].first.first<=B[i].x1; j++)
		{
			root=update(root, 1, SY, VV[j].first.second, VV[j].second);
			//printf("!!%d\n", VV[j].second);
		}
		query(root, 1, SY, B[i].y1, B[i].y2, B[i].p);
		//printf("??%d\n", B[i].p);
	}
 
	VV.clear(); VV.shrink_to_fit();
	for(int i=1; i<=M; i++)
	{
		VV.push_back({{B[i].y1, B[i].x1}, B[i].p});
		VV.push_back({{B[i].y2+1, B[i].x1}, 0});
	}
	sort(VV.begin(), VV.end());
	sort(A+1, A+N+1, [&](const Line &p, const Line &q)
	{
		return p.y1<q.y1;
	});

 
	root=newNode();
	//makeTree(root, 1, SX);
	for(int i=1, j=0; i<=N; i++)
	{
		for(; j<VV.size() && VV[j].first.first<=A[i].y1; j++)
		{
			root=update(root, 1, SX, VV[j].first.second, VV[j].second);
		}
		query(root, 1, SX, A[i].x1, A[i].x2, A[i].p);
	}
 
	VV.clear(); VV.shrink_to_fit();

	sort(adj.begin(), adj.end());

	for(int i=1; i<=N+M; i++)
	{
		if(vis[i]) continue;
		dfs(i);
	}
	reverse(S.begin(), S.end());
	for(auto it : S)
	{
		if(scc[it]) continue;
		++scnt;
		dfs2(it);
	}
	
	sort(scc+1, scc+N+M+1);
	C=unique(scc+1, scc+N+M+1)-scc-1;
 
	ll ans=C-V+E;
	printf("%lld\n", ans);
}

Compilation message

2014_ho_t5.cpp: In function 'int update(int, int, int, int, int)':
2014_ho_t5.cpp:63:12: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   63 |  int mid=tl+tr>>1;
      |          ~~^~~
2014_ho_t5.cpp: In function 'void query(int, int, int, int, int, int)':
2014_ho_t5.cpp:80:12: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   80 |  int mid=tl+tr>>1;
      |          ~~^~~
2014_ho_t5.cpp: In function 'int main()':
2014_ho_t5.cpp:198:10: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<std::pair<std::pair<long long int, long long int>, int> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  198 |   for(; j<VV.size() && VV[j].first.first<=B[i].x1; j++)
      |         ~^~~~~~~~~~
2014_ho_t5.cpp:219:10: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<std::pair<std::pair<long long int, long long int>, int> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  219 |   for(; j<VV.size() && VV[j].first.first<=B[i].x1; j++)
      |         ~^~~~~~~~~~
2014_ho_t5.cpp:245:10: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<std::pair<std::pair<long long int, long long int>, int> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  245 |   for(; j<VV.size() && VV[j].first.first<=A[i].y1; j++)
      |         ~^~~~~~~~~~
2014_ho_t5.cpp:123:7: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  123 |  scanf("%d%d%d", &W, &H, &t);
      |  ~~~~~^~~~~~~~~~~~~~~~~~~~~~
2014_ho_t5.cpp:127:8: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  127 |   scanf("%d%d%d%d", &p.x1, &p.y1, &p.x2, &p.y2);
      |   ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# 결과 실행 시간 메모리 Grader output
1 Correct 4 ms 5100 KB Output is correct
2 Correct 4 ms 5100 KB Output is correct
3 Correct 4 ms 5100 KB Output is correct
4 Correct 4 ms 5100 KB Output is correct
5 Correct 5 ms 5228 KB Output is correct
6 Correct 4 ms 5100 KB Output is correct
7 Correct 8 ms 5608 KB Output is correct
8 Correct 13 ms 6116 KB Output is correct
9 Correct 12 ms 5864 KB Output is correct
10 Correct 13 ms 6116 KB Output is correct
11 Correct 13 ms 6116 KB Output is correct
12 Correct 8 ms 5608 KB Output is correct
13 Correct 13 ms 6116 KB Output is correct
14 Correct 12 ms 5996 KB Output is correct
15 Correct 12 ms 5904 KB Output is correct
16 Correct 4 ms 5100 KB Output is correct
17 Correct 4 ms 5100 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 4 ms 5100 KB Output is correct
2 Correct 4 ms 5100 KB Output is correct
3 Correct 4 ms 5100 KB Output is correct
4 Correct 4 ms 5100 KB Output is correct
5 Correct 5 ms 5228 KB Output is correct
6 Correct 4 ms 5100 KB Output is correct
7 Correct 8 ms 5608 KB Output is correct
8 Correct 13 ms 6116 KB Output is correct
9 Correct 12 ms 5864 KB Output is correct
10 Correct 13 ms 6116 KB Output is correct
11 Correct 13 ms 6116 KB Output is correct
12 Correct 8 ms 5608 KB Output is correct
13 Correct 13 ms 6116 KB Output is correct
14 Correct 12 ms 5996 KB Output is correct
15 Correct 12 ms 5904 KB Output is correct
16 Correct 4 ms 5100 KB Output is correct
17 Correct 4 ms 5100 KB Output is correct
18 Correct 4 ms 5100 KB Output is correct
19 Correct 4 ms 5100 KB Output is correct
20 Correct 5 ms 5100 KB Output is correct
21 Correct 13 ms 6316 KB Output is correct
22 Correct 13 ms 5988 KB Output is correct
23 Correct 15 ms 6244 KB Output is correct
24 Correct 14 ms 6300 KB Output is correct
25 Correct 14 ms 6244 KB Output is correct
26 Correct 12 ms 5864 KB Output is correct
27 Correct 14 ms 6244 KB Output is correct
28 Correct 14 ms 6244 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 9 ms 5736 KB Output is correct
2 Correct 9 ms 5736 KB Output is correct
3 Correct 8 ms 5628 KB Output is correct
4 Correct 14 ms 6264 KB Output is correct
5 Correct 145 ms 18640 KB Output is correct
6 Correct 889 ms 73960 KB Output is correct
7 Correct 2032 ms 146272 KB Output is correct
8 Correct 2017 ms 151040 KB Output is correct
9 Correct 1812 ms 144116 KB Output is correct
10 Correct 1594 ms 137980 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 5 ms 5100 KB Output is correct
2 Correct 14 ms 6244 KB Output is correct
3 Correct 160 ms 21072 KB Output is correct
4 Correct 4 ms 5100 KB Output is correct
5 Correct 14 ms 6244 KB Output is correct
6 Correct 2713 ms 192936 KB Output is correct
7 Correct 65 ms 11112 KB Output is correct
8 Correct 787 ms 74280 KB Output is correct
9 Correct 1435 ms 125820 KB Output is correct
10 Correct 1520 ms 130008 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 4 ms 5100 KB Output is correct
2 Correct 4 ms 5100 KB Output is correct
3 Correct 4 ms 5100 KB Output is correct
4 Correct 4 ms 5100 KB Output is correct
5 Correct 5 ms 5228 KB Output is correct
6 Correct 4 ms 5100 KB Output is correct
7 Correct 8 ms 5608 KB Output is correct
8 Correct 13 ms 6116 KB Output is correct
9 Correct 12 ms 5864 KB Output is correct
10 Correct 13 ms 6116 KB Output is correct
11 Correct 13 ms 6116 KB Output is correct
12 Correct 8 ms 5608 KB Output is correct
13 Correct 13 ms 6116 KB Output is correct
14 Correct 12 ms 5996 KB Output is correct
15 Correct 12 ms 5904 KB Output is correct
16 Correct 4 ms 5100 KB Output is correct
17 Correct 4 ms 5100 KB Output is correct
18 Correct 4 ms 5100 KB Output is correct
19 Correct 4 ms 5100 KB Output is correct
20 Correct 5 ms 5100 KB Output is correct
21 Correct 13 ms 6316 KB Output is correct
22 Correct 13 ms 5988 KB Output is correct
23 Correct 15 ms 6244 KB Output is correct
24 Correct 14 ms 6300 KB Output is correct
25 Correct 14 ms 6244 KB Output is correct
26 Correct 12 ms 5864 KB Output is correct
27 Correct 14 ms 6244 KB Output is correct
28 Correct 14 ms 6244 KB Output is correct
29 Correct 9 ms 5736 KB Output is correct
30 Correct 9 ms 5736 KB Output is correct
31 Correct 8 ms 5628 KB Output is correct
32 Correct 14 ms 6264 KB Output is correct
33 Correct 145 ms 18640 KB Output is correct
34 Correct 889 ms 73960 KB Output is correct
35 Correct 2032 ms 146272 KB Output is correct
36 Correct 2017 ms 151040 KB Output is correct
37 Correct 1812 ms 144116 KB Output is correct
38 Correct 1594 ms 137980 KB Output is correct
39 Correct 5 ms 5100 KB Output is correct
40 Correct 14 ms 6244 KB Output is correct
41 Correct 160 ms 21072 KB Output is correct
42 Correct 4 ms 5100 KB Output is correct
43 Correct 14 ms 6244 KB Output is correct
44 Correct 2713 ms 192936 KB Output is correct
45 Correct 65 ms 11112 KB Output is correct
46 Correct 787 ms 74280 KB Output is correct
47 Correct 1435 ms 125820 KB Output is correct
48 Correct 1520 ms 130008 KB Output is correct
49 Correct 13 ms 6116 KB Output is correct
50 Correct 16 ms 6124 KB Output is correct
51 Correct 12 ms 6032 KB Output is correct
52 Correct 1146 ms 94156 KB Output is correct
53 Correct 922 ms 73508 KB Output is correct
54 Correct 1205 ms 97412 KB Output is correct
55 Correct 2770 ms 192624 KB Output is correct
56 Correct 2097 ms 150112 KB Output is correct
57 Correct 2786 ms 199424 KB Output is correct
58 Correct 2604 ms 192388 KB Output is correct
59 Correct 1156 ms 99048 KB Output is correct
60 Correct 1518 ms 130688 KB Output is correct
61 Correct 2012 ms 156984 KB Output is correct
62 Correct 2084 ms 157692 KB Output is correct
63 Correct 2726 ms 196740 KB Output is correct
64 Correct 1787 ms 144124 KB Output is correct
65 Correct 2690 ms 198344 KB Output is correct
66 Correct 2681 ms 197092 KB Output is correct
67 Correct 2398 ms 177408 KB Output is correct
68 Correct 2337 ms 177804 KB Output is correct
69 Correct 2426 ms 177820 KB Output is correct
70 Correct 2447 ms 177652 KB Output is correct
71 Correct 1842 ms 139848 KB Output is correct
72 Correct 1880 ms 140304 KB Output is correct