This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
/*
JOISC 17-port_facility
Let's define a graph where each container is a vertex and we draw edges between two containers which can't be put in the same area.
Therefore, the answer will be 2^(number of connected components) or 0 if the graph isn't bipartite(this can be checked beforehand with some simulation).
Since the number of edges can be really big, we need segment tree to reduce the number of edges we are going to use.
*/
#include<bits/stdc++.h>
#define god dimasi5eks
#pragma GCC optimize("O3")
#define fi first
#define se second
#define pb push_back
#define pf push_front
#define mod 1000000007
#define dancila 3.14159265359
#define eps 1e-9
// #define fisier 1
using namespace std;
typedef long long ll;
int n;
pair<int, int> bk[1000002];
int poz[2000002];
void chk()
{
vector<int> d[2];
for(int i = 1; i <= n; ++i)
{
for(int j = 0; j <= 1; ++j)
while(!d[j].empty() && d[j].back() < bk[i].fi)
d[j].pop_back();
if(d[0].empty() && d[1].empty())
d[0].pb(bk[i].se);
else
if(d[1].empty())
{
if(bk[i].se < d[0].back())
d[0].pb(bk[i].se);
else
d[1].pb(bk[i].se);
}
else
if(d[0].empty())
{
if(bk[i].se < d[1].back())
d[1].pb(bk[i].se);
else
d[0].pb(bk[i].se);
}
else
{
if(bk[i].se > max((int) d[0].back(), (int) d[1].back()))
{
cout << 0 << '\n';
exit(0);
}
if(d[0].back() < d[1].back())
{
if(bk[i].se < d[0].back())
d[0].pb(bk[i].se);
else
d[1].pb(bk[i].se);
}
else
{
if(bk[i].se < d[1].back())
d[1].pb(bk[i].se);
else
d[0].pb(bk[i].se);
}
}
}
}
int aint[8000002], aint2[8000002];
void upd(int nod, int st, int dr, int poz, int val)
{
if(st == dr)
{
aint[nod] = val;
return;
}
int mid = (st + dr) / 2;
if(poz <= mid)
upd(nod << 1, st, mid, poz, val);
else
upd(nod << 1|1, mid+1, dr, poz, val);
aint[nod] = max(aint[nod << 1], aint[nod << 1|1]);
}
int query(int nod, int st, int dr, int L, int R)
{
if(dr < L || st > R)
return -(1<<30);
if(L <= st && dr <= R)
return aint[nod];
int mid = (st + dr) / 2;
return max(query(nod << 1, st, mid, L, R), query(nod << 1|1, mid+1, dr, L, R));
}
void upd2(int nod, int st, int dr, int poz, int val)
{
if(st == dr)
{
aint2[nod] = val;
return;
}
int mid = (st + dr) / 2;
if(poz <= mid)
upd2(nod << 1, st, mid, poz, val);
else
upd2(nod << 1|1, mid+1, dr, poz, val);
aint2[nod] = min(aint2[nod << 1], aint2[nod << 1|1]);
}
int query2(int nod, int st, int dr, int L, int R)
{
if(dr < L || st > R)
return (1<<30);
if(L <= st && dr <= R)
return aint2[nod];
int mid = (st + dr) / 2;
return min(query2(nod << 1, st, mid, L, R), query2(nod << 1|1, mid+1, dr, L, R));
}
bool viz[1000002];
void dfs(int nod)
{
viz[nod] = 1;
upd(1, 1, n+n, bk[nod].fi, -(1<<30));
upd2(1, 1, n+n, bk[nod].se, (1<<30));
while(1)
{
int val = (1<<30);
if(bk[nod].fi + 1 <= bk[nod].se - 1)
val = query2(1, 1, n+n, bk[nod].fi + 1, bk[nod].se - 1);
// cout << "A " << nod << " " << val << '\n';
if(val < bk[nod].fi)
dfs(poz[val]);
else
break;
}
while(1)
{
int val = -(1<<30);
if(bk[nod].fi + 1 <= bk[nod].se - 1)
val = query(1, 1, n+n, bk[nod].fi + 1, bk[nod].se - 1);
// cout << "B " << nod << " " << val << '\n';
if(val > bk[nod].se)
dfs(poz[val]);
else
break;
}
}
int main()
{
#ifdef fisier
ifstream f("input.in");
ofstream g("output.out");
#endif
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cin >> n;
for(int i = 1; i <= n+n; ++i)
{
upd(1, 1, n+n, i, -(1<<30));
upd2(1, 1, n+n, i, (1<<30));
}
for(int i = 1; i <= n; ++i)
{
cin >> bk[i].fi >> bk[i].se;
poz[bk[i].fi] = poz[bk[i].se] = i;
upd(1, 1, n+n, bk[i].fi, bk[i].se);
upd2(1, 1, n+n, bk[i].se, bk[i].fi);
}
int ans = 1;
for(int i = 1; i <= n; ++i)
if(!viz[i])
{
ans = (ans * 2) % mod;
dfs(i);
}
sort(bk + 1, bk + n + 1);
chk();
cout << ans << '\n';
return 0;
}
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |