Submission #9491578
Source Code Expand
use mod_int::ModInt;
const MOD: usize = 998244353;
fn main() {
let (r, w) = (std::io::stdin(), std::io::stdout());
let mut sc = IO::new(r.lock(), w.lock());
let n: usize = sc.read();
let mut x = vec![];
let mut y = vec![];
for _ in 0..n {
x.push(sc.read::<i64>());
y.push(sc.read::<i64>());
}
let mut xi = x.clone();
xi.sort();
xi.dedup();
let x = x
.into_iter()
.map(|x| xi.binary_search(&x).unwrap())
.collect::<Vec<_>>();
let mut yi = y.clone();
yi.sort();
yi.dedup();
let y = y
.into_iter()
.map(|y| yi.binary_search(&y).unwrap())
.collect::<Vec<_>>();
let mut xy = x.into_iter().zip(y.into_iter()).collect::<Vec<_>>();
xy.sort();
let mut top_right = vec![0; n];
let mut top_left = vec![0; n];
let mut bottom_right = vec![0; n];
let mut bottom_left = vec![0; n];
let mut bit = fenwick_tree::FenwickTree::new(n, 0);
for i in 0..n {
let (_, y) = xy[i];
let lower = bit.sum(0, y);
let upper = i - lower;
top_left[i] = upper;
bottom_left[i] = lower;
bit.add(y, 1);
}
let mut bit = fenwick_tree::FenwickTree::new(n, 0);
for i in (0..n).rev() {
let (_, y) = xy[i];
let lower = bit.sum(0, y);
let upper = (n - 1 - i) - lower;
top_right[i] = upper;
bottom_right[i] = lower;
bit.add(y, 1);
}
let mut pow2 = vec![ModInt(1); n];
for i in 1..n {
pow2[i] = pow2[i - 1] * 2;
}
let mut ans = pow2[n - 1] * n;
for i in 0..n {
for mask in 0..(1 << 4) {
let tl = mask & 1 != 0;
let tr = mask & (1 << 1) != 0;
let bl = mask & (1 << 2) != 0;
let br = mask & (1 << 3) != 0;
if (tl && br) || (tr && bl) {
let mut add = ModInt(1);
if tl {
add *= pow2[top_left[i]] - 1;
}
if tr {
add *= pow2[top_right[i]] - 1;
}
if bl {
add *= pow2[bottom_left[i]] - 1;
}
if br {
add *= pow2[bottom_right[i]] - 1;
}
ans += add;
}
}
}
println!("{}", ans.0);
}
pub mod mod_int {
use super::MOD;
use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign};
type Num = usize;
#[derive(Clone, Copy)]
pub struct ModInt<T: Copy + Clone>(pub T);
impl Add<ModInt<Num>> for ModInt<Num> {
type Output = ModInt<Num>;
fn add(self, rhs: ModInt<Num>) -> ModInt<Num> {
self + rhs.0
}
}
impl Add<Num> for ModInt<Num> {
type Output = ModInt<Num>;
fn add(self, rhs: Num) -> ModInt<Num> {
let mut t = rhs + self.0;
if t >= MOD {
t = t - MOD;
}
ModInt(t)
}
}
impl Sub<Num> for ModInt<Num> {
type Output = ModInt<Num>;
fn sub(self, rhs: Num) -> ModInt<Num> {
let rhs = if rhs >= MOD { rhs % MOD } else { rhs };
let value = if self.0 < rhs { self.0 + MOD } else { self.0 };
ModInt(value - rhs)
}
}
impl Sub<ModInt<Num>> for ModInt<Num> {
type Output = ModInt<Num>;
fn sub(self, rhs: ModInt<Num>) -> ModInt<Num> {
self - rhs.0
}
}
impl AddAssign<Num> for ModInt<Num> {
fn add_assign(&mut self, other: Num) {
*self = *self + other;
}
}
impl AddAssign<ModInt<Num>> for ModInt<Num> {
fn add_assign(&mut self, other: ModInt<Num>) {
*self = *self + other;
}
}
impl SubAssign<Num> for ModInt<Num> {
fn sub_assign(&mut self, other: Num) {
*self = *self - other;
}
}
impl SubAssign<ModInt<Num>> for ModInt<Num> {
fn sub_assign(&mut self, other: ModInt<Num>) {
*self = *self - other;
}
}
impl Div<Num> for ModInt<Num> {
type Output = ModInt<Num>;
fn div(self, rhs: Num) -> ModInt<Num> {
self * ModInt(rhs).pow(MOD - 2)
}
}
impl Div<ModInt<Num>> for ModInt<Num> {
type Output = ModInt<Num>;
fn div(self, rhs: ModInt<Num>) -> ModInt<Num> {
self / rhs.0
}
}
impl DivAssign<Num> for ModInt<Num> {
fn div_assign(&mut self, rhs: Num) {
*self = *self / rhs
}
}
impl DivAssign<ModInt<Num>> for ModInt<Num> {
fn div_assign(&mut self, rhs: ModInt<Num>) {
*self = *self / rhs
}
}
impl Mul<ModInt<Num>> for ModInt<Num> {
type Output = ModInt<Num>;
fn mul(self, rhs: ModInt<Num>) -> ModInt<Num> {
self * rhs.0
}
}
impl Mul<Num> for ModInt<Num> {
type Output = ModInt<Num>;
fn mul(self, rhs: Num) -> ModInt<Num> {
let t = (self.0 * rhs) % MOD;
ModInt(t)
}
}
impl MulAssign<Num> for ModInt<Num> {
fn mul_assign(&mut self, rhs: Num) {
*self = *self * rhs;
}
}
impl MulAssign<ModInt<Num>> for ModInt<Num> {
fn mul_assign(&mut self, rhs: ModInt<Num>) {
*self = *self * rhs;
}
}
impl ModInt<Num> {
pub fn pow(self, e: usize) -> ModInt<Num> {
let mut result = ModInt(1);
let mut cur = self;
let mut e = e;
while e > 0 {
if e & 1 == 1 {
result *= cur;
}
e >>= 1;
cur *= cur;
}
result
}
}
}
pub mod fenwick_tree {
/// `FenwickTree` is a data structure that can efficiently update elements
/// and calculate prefix sums in a table of numbers.
/// [https://en.wikipedia.org/wiki/Fenwick_tree](https://en.wikipedia.org/wiki/Fenwick_tree)
pub struct FenwickTree<T> {
n: usize,
data: Vec<T>,
init: T,
}
impl<T: Copy + ::std::ops::AddAssign + ::std::ops::Sub<Output = T>> FenwickTree<T> {
/// Constructs a new `FenwickTree`. The size of `FenwickTree` should be specified by `size`.
pub fn new(size: usize, init: T) -> FenwickTree<T> {
FenwickTree {
n: size + 1,
data: vec![init; size + 1],
init: init,
}
}
pub fn add(&mut self, k: usize, value: T) {
let mut x = k;
while x < self.n {
self.data[x] += value;
x |= x + 1;
}
}
/// Returns a sum of range `[l, r)`
pub fn sum(&self, l: usize, r: usize) -> T {
self.sum_one(r) - self.sum_one(l)
}
/// Returns a sum of range `[0, k)`
pub fn sum_one(&self, k: usize) -> T {
assert!(k < self.n, "k={} n={}", k, self.n);
let mut result = self.init;
let mut x = k as i32 - 1;
while x >= 0 {
result += self.data[x as usize];
x = (x & (x + 1)) - 1;
}
result
}
}
}
pub struct IO<R, W: std::io::Write>(R, std::io::BufWriter<W>);
impl<R: std::io::Read, W: std::io::Write> IO<R, W> {
pub fn new(r: R, w: W) -> IO<R, W> {
IO(r, std::io::BufWriter::new(w))
}
pub fn write<S: std::ops::Deref<Target = str>>(&mut self, s: S) {
use std::io::Write;
self.1.write(s.as_bytes()).unwrap();
}
pub fn read<T: std::str::FromStr>(&mut self) -> T {
use std::io::Read;
let buf = self
.0
.by_ref()
.bytes()
.map(|b| b.unwrap())
.skip_while(|&b| b == b' ' || b == b'\n' || b == b'\r' || b == b'\t')
.take_while(|&b| b != b' ' && b != b'\n' && b != b'\r' && b != b'\t')
.collect::<Vec<_>>();
unsafe { std::str::from_utf8_unchecked(&buf) }
.parse()
.ok()
.expect("Parse error.")
}
pub fn vec<T: std::str::FromStr>(&mut self, n: usize) -> Vec<T> {
(0..n).map(|_| self.read()).collect()
}
pub fn chars(&mut self) -> Vec<char> {
self.read::<String>().chars().collect()
}
}
Submission Info
| Submission Time |
|
| Task |
F - Enclosed Points |
| User |
kenkoooo |
| Language |
Rust (1.15.1) |
| Score |
600 |
| Code Size |
8731 Byte |
| Status |
AC |
| Exec Time |
308 ms |
| Memory |
26552 KiB |
Judge Result
| Set Name |
Sample |
All |
| Score / Max Score |
0 / 0 |
600 / 600 |
| Status |
|
|
| Set Name |
Test Cases |
| Sample |
s1.txt, s2.txt, s3.txt |
| All |
01.txt, 02.txt, 03.txt, 04.txt, 05.txt, 06.txt, 07.txt, 08.txt, 09.txt, 10.txt, 11.txt, 12.txt, 13.txt, 14.txt, 15.txt, 16.txt, 17.txt, 18.txt, 19.txt, 20.txt, 21.txt, 22.txt, 23.txt, s1.txt, s2.txt, s3.txt |
| Case Name |
Status |
Exec Time |
Memory |
| 01.txt |
AC |
2 ms |
4352 KiB |
| 02.txt |
AC |
2 ms |
4352 KiB |
| 03.txt |
AC |
2 ms |
4352 KiB |
| 04.txt |
AC |
2 ms |
4352 KiB |
| 05.txt |
AC |
2 ms |
4352 KiB |
| 06.txt |
AC |
2 ms |
4352 KiB |
| 07.txt |
AC |
2 ms |
4352 KiB |
| 08.txt |
AC |
2 ms |
4352 KiB |
| 09.txt |
AC |
2 ms |
4352 KiB |
| 10.txt |
AC |
2 ms |
4352 KiB |
| 11.txt |
AC |
308 ms |
26456 KiB |
| 12.txt |
AC |
301 ms |
23652 KiB |
| 13.txt |
AC |
306 ms |
26544 KiB |
| 14.txt |
AC |
297 ms |
23528 KiB |
| 15.txt |
AC |
306 ms |
26536 KiB |
| 16.txt |
AC |
307 ms |
26536 KiB |
| 17.txt |
AC |
307 ms |
26540 KiB |
| 18.txt |
AC |
308 ms |
26540 KiB |
| 19.txt |
AC |
296 ms |
26552 KiB |
| 20.txt |
AC |
290 ms |
23652 KiB |
| 21.txt |
AC |
303 ms |
26540 KiB |
| 22.txt |
AC |
301 ms |
26536 KiB |
| 23.txt |
AC |
2 ms |
4352 KiB |
| s1.txt |
AC |
2 ms |
4352 KiB |
| s2.txt |
AC |
2 ms |
4352 KiB |
| s3.txt |
AC |
2 ms |
4352 KiB |