This repository has been archived by the owner on Sep 5, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
55 changed files
with
2,074,067 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
# -*- coding: utf-8; mode: python -*- | ||
|
||
pid='loneliness' | ||
|
||
problem( | ||
time_limit=2.0, | ||
id=pid, | ||
title="Loneliness", | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,138 @@ | ||
# Loneliness | ||
|
||
実行時間制限:2 sec | ||
|
||
## 問題文 | ||
|
||
数直線上に人がいます。\ | ||
それぞれの人は $1, 2, ... , 60$ のクラスのうち 1 つに属しています。\ | ||
同じクラスの人は 2 人で 1 つのペアを組むことができます。<br> | ||
|
||
$Q$ 個のクエリが与えられるので順に処理してください。各クエリは次の | ||
2 種類のどちらかです。 | ||
|
||
- `1 L R l r`:区間 $\lbrack L, R \rparen$ 内にクラス $l, l+1, ... , r$ の人がそれぞれ奇数人、それ以外のクラスの人は偶数人いるという情報が与えられる。 | ||
- `2 L R`:区間 $\lbrack L, R \rparen$ にいる人で可能な限りペアを組んだ場合に、ペアになれずに残る人数を出力する。質問の時点で答えが一通りに定まらない場合は、代わりに `Ambiguous` と出力する。 | ||
|
||
なお、各人は複数の区間にまたがることはないものとします。 | ||
|
||
## 制約 | ||
|
||
- $1 \leq Q \leq 2 \times 10^5$ | ||
- $1 \leq L < R \leq 10^9$ | ||
- $1 \leq l \leq r \leq 60$ | ||
- 入力は全て整数である。 | ||
- 矛盾するような入力は与えられない。 | ||
- `2 L R` のクエリは少なくとも 1 回以上与えられる。 | ||
|
||
## 部分点 | ||
|
||
この問題はいくつかの小課題に分けられ、その小課題の全てのテストケースに正解した場合に、「この小課題に正解した」とみなされます。 | ||
提出したソースコードの得点は、正解した小課題の点数の合計となります。 | ||
|
||
1. (20 点) $Q \leq 3000$ を満たす。 | ||
2. (80 点) 追加の制約はない。 | ||
|
||
## 入力 | ||
|
||
入力は以下の形式で与えられます。 | ||
|
||
```txt | ||
Q | ||
Query_1 | ||
Query_2 | ||
: | ||
Query_Q | ||
``` | ||
|
||
## 出力 | ||
|
||
`2 L R` のクエリに対する答えを、1 行に 1 つずつ、順に出力せよ。 | ||
|
||
### 入力例 1 | ||
|
||
```txt | ||
7 | ||
1 1 3 2 2 | ||
2 1 3 | ||
1 1 2 1 1 | ||
2 1 4 | ||
2 2 3 | ||
1 2 4 1 2 | ||
2 3 4 | ||
``` | ||
|
||
### 出力例 1 | ||
|
||
```txt | ||
1 | ||
Ambiguous | ||
2 | ||
0 | ||
``` | ||
|
||
1 つ目のクエリでは、区間 $\lbrack 1, 3 \rparen$ にはクラス 2 の人が奇数人、それ以外のクラス 1, 3 の人が偶数人いるという情報が得られます。<br> | ||
3 つ目のクエリでは、区間 $\lbrack 1, 2 \rparen$ にはクラス 1 の人が奇数人、それ以外のクラス 2, 3 の人が偶数人存在するという情報が得られます。<br> | ||
5 つ目のクエリでは、区間 $\lbrack 2, 3 \rparen$ にクラス 1, 2, 3 の人はそれぞれ奇数, 奇数, 偶数人存在することが分かるので、ペアになれずに残る人は 2 人です。 | ||
|
||
なお、この入力例は小課題 1, 2 の制約を満たします。 | ||
|
||
### 入力例 2 | ||
|
||
```txt | ||
9 | ||
2 1 2 | ||
1 1 3 1 60 | ||
1 1 2 1 30 | ||
1 2 3 31 60 | ||
1 2 3 31 60 | ||
2 1 2 | ||
2 1 2 | ||
2 1 3 | ||
2 2 3 | ||
``` | ||
|
||
### 出力例 2 | ||
|
||
```txt | ||
Ambiguous | ||
30 | ||
30 | ||
60 | ||
30 | ||
``` | ||
|
||
1 つ目のクエリでは、区間 $\lbrack 1, 2 \rparen$ の人に関する情報がなく、答えが一通りに定まらないため `Ambiguous` と出力します。<br> | ||
同じクエリが何度も出現する場合もあるので注意してください。<br> | ||
なお、この入力例は小課題 1, 2 の制約を満たします。 | ||
|
||
## 解法 | ||
|
||
- `sol-cpp-partial1`: C++ 部分点 1 | ||
- `sol-py-partial1`: Python 部分点 1 | ||
- `sol-cpp-ac`: C++ AC | ||
- `sol-py-ac`: Python AC | ||
|
||
### 部分点 1 解法 | ||
|
||
まず、今回はクエリで現れる区間の長さは特に考慮しないため、クエリを先読みして座標圧縮をしても問題ありません。<br> | ||
|
||
また、ある区間 $\lbrack L , R \rparen$ において、各クラスでペアを作れずに余る人は 0 or 1 人しかいません。即ち、答えはある区間 $\lbrack L , R \rparen$ における各クラスの人数の mod 2 の総和に等しいです。<br> | ||
|
||
ここで $B_{L,R}$ 以下を定義します。 | ||
|
||
$$B_{L,R} = \sum_{i=1}^{60} 2^{i-1}\times (区間 \ \lbrack L , R \rparen \ にいるクラス \ i \ の人数 \ \text{mod 2})$$ | ||
|
||
これは、 $(B_{L,R} \land (1 \ll i)) \neq 0$ の時、区間 $\lbrack L , R \rparen$ にクラス $i$ の人が奇数人存在することを意味する値です。 | ||
|
||
$L < M < R$ において、 $B_{L,M} \oplus B_{M,R}$ を考えると、これは桁毎に見ると mod 2 の和に等しいため、二つの区間の情報を統合させたものとして相応しく $B_{L,R}$ に等しいです。 | ||
|
||
これにより、クエリ 1 の $L, R$ 間にコスト $B_{L,R}$ の辺を張ったグラフを考え、クエリ 2 における $L$ を始点として移動時にコストで XOR を取るような BFS を行うことで、$R$ に到着した時のコストの pop count がクエリ 2 の答えになります。<br> | ||
|
||
クエリは $Q$ 個なので、このグラフにおける頂点・辺の数は高々 $2Q$ 個であるため、 $O(Q^2)$ で解くことができます。 | ||
|
||
### 満点解法 | ||
|
||
クエリ 1 で与えられる情報の端点を移動して $L$ から $R$ にたどり着けるとき、経路に依らず $B_{L,R}$ が一意に定まることがわかります。<br> | ||
よって、これはポテンシャルの概念と同じくとらえることができ、重み付き UnionFind の重みとして $B_{L,R}$ を管理することで $O(Q)$ で解くことができます。 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# -*- coding: utf-8; mode: python -*- | ||
cxx_solution(src='main.cc', flags=["-std=c++2a", "-O2"]) | ||
expected_score(100) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
#include <bits/stdc++.h> | ||
using namespace std; | ||
|
||
using ll = long long; | ||
struct weighted_dsu { | ||
public: | ||
weighted_dsu(): _n(0) {} | ||
explicit weighted_dsu(ll n): _n(n), parent_or_size(n, -1), diff_weight(n, 0) {} | ||
|
||
ll merge(ll a, ll b, ll w) { | ||
assert(0 <= a && a < _n); | ||
assert(0 <= b && b < _n); | ||
|
||
w ^= weight(a); | ||
w ^= weight(b); | ||
|
||
ll x = leader(a), y = leader(b); | ||
if(x == y) return x; | ||
if(-parent_or_size[x] < -parent_or_size[y]) swap(x, y); | ||
|
||
parent_or_size[x] += parent_or_size[y]; | ||
parent_or_size[y] = x; | ||
diff_weight[y] = w; | ||
|
||
return x; | ||
} | ||
|
||
bool same(ll a, ll b) { | ||
assert(0 <= a && a < _n); | ||
assert(0 <= b && b < _n); | ||
return leader(a) == leader(b); | ||
} | ||
|
||
ll leader(ll a) { | ||
assert(0 <= a && a < _n); | ||
if(parent_or_size[a] < 0) return a; | ||
ll r = leader(parent_or_size[a]); | ||
diff_weight[a] ^= diff_weight[parent_or_size[a]]; | ||
return parent_or_size[a] = r; | ||
} | ||
|
||
ll weight(ll x) { | ||
leader(x); // 経路圧縮 | ||
return diff_weight[x]; | ||
} | ||
|
||
ll diff(ll x, ll y) { | ||
return weight(y) ^ weight(x); | ||
} | ||
|
||
private: | ||
ll _n; | ||
vector<ll> parent_or_size; | ||
vector<ll> diff_weight; | ||
}; | ||
|
||
int main() { | ||
cin.tie(nullptr); | ||
ios_base::sync_with_stdio(false); | ||
|
||
int q; | ||
cin >> q; | ||
vector<int> comp; | ||
vector<tuple<int, int, int, int, int>> query; | ||
for(int i = 0; i < q; i++) { | ||
int t, L, R, l = -1, r = -1; | ||
cin >> t >> L >> R; | ||
comp.emplace_back(L); | ||
comp.emplace_back(R); | ||
if(t == 1) cin >> l >> r; | ||
query.emplace_back(tuple(t, L, R, l, r)); | ||
} | ||
sort(comp.begin(), comp.end()); | ||
comp.erase(unique(comp.begin(), comp.end()), comp.end()); | ||
for(auto& [t, L, R, l, r]: query) { | ||
L = lower_bound(comp.begin(), comp.end(), L) - comp.begin(); | ||
R = lower_bound(comp.begin(), comp.end(), R) - comp.begin(); | ||
} | ||
|
||
weighted_dsu uf(comp.size()); | ||
for(auto& [t, L, R, l, r]: query) { | ||
if(t == 1) uf.merge(L, R, (1LL << r) - (1LL << (l - 1))); | ||
else { | ||
if(!uf.same(L, R)) cout << "Ambiguous\n"; | ||
else cout << __builtin_popcountll(uf.diff(L, R)) << '\n'; | ||
} | ||
} | ||
|
||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# -*- coding: utf-8; mode: python -*- | ||
cxx_solution(src='main.cc', flags=["-std=c++2a", "-O2"], challenge_cases=["*_all.in"]) | ||
expected_score(10) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
#include <bits/stdc++.h> | ||
using namespace std; | ||
|
||
using ll = long long; | ||
|
||
int main() { | ||
cin.tie(nullptr); | ||
ios_base::sync_with_stdio(false); | ||
|
||
int q; | ||
cin >> q; | ||
vector<int> comp; | ||
vector<tuple<int, int, int, int, int>> query; | ||
for(int i = 0; i < q; i++) { | ||
int t, L, R, l = -1, r = -1; | ||
cin >> t >> L >> R; | ||
comp.emplace_back(L); | ||
comp.emplace_back(R); | ||
if(t == 1) cin >> l >> r; | ||
query.emplace_back(tuple(t, L, R, l, r)); | ||
} | ||
sort(comp.begin(), comp.end()); | ||
comp.erase(unique(comp.begin(), comp.end()), comp.end()); | ||
for(auto& [t, L, R, l, r]: query) { | ||
L = lower_bound(comp.begin(), comp.end(), L) - comp.begin(); | ||
R = lower_bound(comp.begin(), comp.end(), R) - comp.begin(); | ||
} | ||
|
||
vector<vector<tuple<int, int, int>>> Graph(comp.size()); | ||
for(auto& [t, L, R, l, r]: query) { | ||
if(t == 1) { | ||
Graph[L].emplace_back(R, l, r); | ||
Graph[R].emplace_back(L, l, r); | ||
} else { | ||
// 愚直に Graph 上を探索 | ||
vector<bool> visited(comp.size(), false); | ||
queue<pair<int, ll>> que; | ||
que.push({L, 0}); | ||
|
||
bool arrived = false; | ||
while(!que.empty()) { | ||
auto [now, bit] = que.front(); | ||
que.pop(); | ||
if(now == R) { | ||
cout << __builtin_popcountll(bit) << '\n'; | ||
arrived = true; | ||
break; | ||
} | ||
if(visited[now]) continue; | ||
visited[now] = true; | ||
for(auto [to, nl, nr]: Graph[now]) { | ||
if(visited[to]) continue; | ||
que.push({to, bit ^ ((1LL << nr) - (1LL << (nl - 1)))}); | ||
} | ||
} | ||
if(!arrived) cout << "Ambiguous\n"; | ||
} | ||
} | ||
|
||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# -*- coding: utf-8; mode: python -*- | ||
script_solution(src='main.py') | ||
expected_score(100) |
Oops, something went wrong.