제출 #1005351

#제출 시각아이디문제언어결과실행 시간메모리
1005351jonathanirvingsFlooding Wall (BOI24_wall)C++17
70 / 100
5057 ms66824 KiB
//start of jonathanirvings' template v3.0.3 (BETA) #include <bits/stdc++.h> using namespace std; typedef long long LL; typedef pair<int,int> pii; typedef pair<LL,LL> pll; typedef pair<string,string> pss; typedef vector<int> vi; typedef vector<vi> vvi; typedef vector<pii> vii; typedef vector<LL> vl; typedef vector<vl> vvl; double EPS = 1e-9; int INF = 1000000005; long long INFF = 1000000000000000005LL; double PI = acos(-1); int dirx[8] = {-1,0,0,1,-1,-1,1,1}; int diry[8] = {0,1,-1,0,-1,1,-1,1}; #ifdef TESTING #define DEBUG fprintf(stderr,"====TESTING====\n") #define VALUE(x) cerr << "The value of " << #x << " is " << x << endl #define debug(...) fprintf(stderr, __VA_ARGS__) #else #define DEBUG #define VALUE(x) #define debug(...) #endif #define FOR(a,b,c) for (int (a)=(b);(a)<(c);++(a)) #define FORN(a,b,c) for (int (a)=(b);(a)<=(c);++(a)) #define FORD(a,b,c) for (int (a)=(b);(a)>=(c);--(a)) #define FORSQ(a,b,c) for (int (a)=(b);(a)*(a)<=(c);++(a)) #define FORC(a,b,c) for (char (a)=(b);(a)<=(c);++(a)) #define FOREACH(a,b) for (auto &(a) : (b)) #define REP(i,n) FOR(i,0,n) #define REPN(i,n) FORN(i,1,n) #define MAX(a,b) a = max(a,b) #define MIN(a,b) a = min(a,b) #define SQR(x) ((LL)(x) * (x)) #define RESET(a,b) memset(a,b,sizeof(a)) #define fi first #define se second #define mp make_pair #define pb push_back #define ALL(v) v.begin(),v.end() #define ALLA(arr,sz) arr,arr+sz #define SIZE(v) (int)v.size() #define SORT(v) sort(ALL(v)) #define REVERSE(v) reverse(ALL(v)) #define SORTA(arr,sz) sort(ALLA(arr,sz)) #define REVERSEA(arr,sz) reverse(ALLA(arr,sz)) #define PERMUTE next_permutation #define TC(t) while(t--) inline string IntToString(LL a){ char x[100]; sprintf(x,"%lld",a); string s = x; return s; } inline LL StringToInt(string a){ char x[100]; LL res; strcpy(x,a.c_str()); sscanf(x,"%lld",&res); return res; } inline string GetString(void){ char x[1000005]; scanf("%s",x); string s = x; return s; } inline string uppercase(string s){ int n = SIZE(s); REP(i,n) if (s[i] >= 'a' && s[i] <= 'z') s[i] = s[i] - 'a' + 'A'; return s; } inline string lowercase(string s){ int n = SIZE(s); REP(i,n) if (s[i] >= 'A' && s[i] <= 'Z') s[i] = s[i] - 'A' + 'a'; return s; } inline void OPEN (string s) { #ifndef TESTING freopen ((s + ".in").c_str (), "r", stdin); freopen ((s + ".out").c_str (), "w", stdout); #endif } //end of jonathanirvings' template v3.0.3 (BETA) template <int Mod> struct ModInt { ModInt() : num_(0) {} template <class T> ModInt(T num) { long long x = (long long)(num % (long long)(Mod)); if (x < 0) x += Mod; num_ = (int)(x); } ModInt& operator++() { num_++; if (num_ == Mod) num_ = 0; return *this; } ModInt& operator--() { if (num_ == 0) num_ = Mod; num_--; return *this; } ModInt operator++(int) { ModInt result = *this; ++*this; return result; } ModInt operator--(int) { ModInt result = *this; --*this; return result; } ModInt& operator+=(const ModInt& rhs) { num_ += rhs.num_; if (num_ >= Mod) num_ -= Mod; return *this; } ModInt& operator-=(const ModInt& rhs) { num_ -= rhs.num_; if (num_ < 0) num_ += Mod; return *this; } ModInt& operator*=(const ModInt& rhs) { long long z = num_; z *= rhs.num_; num_ = (int)(z % Mod); return *this; } ModInt& operator/=(const ModInt& rhs) { return *this = *this * rhs.inv(); } ModInt operator+() const { return *this; } ModInt operator-() const { return ModInt() - *this; } ModInt pow(long long n) const { assert(0 <= n); ModInt x = *this, r = 1; while (n) { if (n & 1) r *= x; x *= x; n >>= 1; } return r; } ModInt inv() const { return pow(Mod - 2); } friend ModInt operator+(const ModInt& lhs, const ModInt& rhs) { return ModInt(lhs) += rhs; } friend ModInt operator-(const ModInt& lhs, const ModInt& rhs) { return ModInt(lhs) -= rhs; } friend ModInt operator*(const ModInt& lhs, const ModInt& rhs) { return ModInt(lhs) *= rhs; } friend ModInt operator/(const ModInt& lhs, const ModInt& rhs) { return ModInt(lhs) /= rhs; } friend bool operator==(const ModInt& lhs, const ModInt& rhs) { return lhs.num_ == rhs.num_; } friend bool operator!=(const ModInt& lhs, const ModInt& rhs) { return lhs.num_ != rhs.num_; } int get() const { return num_; } int num_; }; template <int Mod> struct ModBinomCoeff { ModBinomCoeff() {} ModBinomCoeff(int N) : fact_(N + 1), inv_fact_(N + 1) { fact_[0] = 1; for (int i = 1; i <= N; ++i) { fact_[i] = fact_[i - 1] * (i); } inv_fact_[N] = fact_[N].inv(); for (int i = N - 1; i >= 0; --i) { inv_fact_[i] = inv_fact_[i + 1] * (i + 1); } } ModInt<Mod> fact(int N) { assert(N < fact_.size()); return fact_[N]; } ModInt<Mod> choose(int N, int K) { assert(N < fact_.size()); return fact_[N] * inv_fact_[K] * inv_fact_[N - K]; } vector<ModInt<Mod>> fact_; vector<ModInt<Mod>> inv_fact_; }; constexpr int Mod998244353 = 998244353; constexpr int Mod1000000007 = 1000000007; constexpr int Mod = Mod1000000007; using Int = ModInt<Mod>; #ifndef ATCODER_LAZYSEGTREE_HPP #define ATCODER_LAZYSEGTREE_HPP 1 #include <algorithm> #include <cassert> #include <functional> #include <vector> #ifndef ATCODER_INTERNAL_BITOP_HPP #define ATCODER_INTERNAL_BITOP_HPP 1 #ifdef _MSC_VER #include <intrin.h> #endif #if __cplusplus >= 202002L #include <bit> #endif namespace atcoder { namespace internal { #if __cplusplus >= 202002L using std::bit_ceil; #else // @return same with std::bit::bit_ceil unsigned int bit_ceil(unsigned int n) { unsigned int x = 1; while (x < (unsigned int)(n)) x *= 2; return x; } #endif // @param n `1 <= n` // @return same with std::bit::countr_zero int countr_zero(unsigned int n) { #ifdef _MSC_VER unsigned long index; _BitScanForward(&index, n); return index; #else return __builtin_ctz(n); #endif } // @param n `1 <= n` // @return same with std::bit::countr_zero constexpr int countr_zero_constexpr(unsigned int n) { int x = 0; while (!(n & (1 << x))) x++; return x; } } // namespace internal } // namespace atcoder #endif // ATCODER_INTERNAL_BITOP_HPP namespace atcoder { #if __cplusplus >= 201703L template <class S, auto op, auto e, class F, auto mapping, auto composition, auto id> struct lazy_segtree { static_assert(std::is_convertible_v<decltype(op), std::function<S(S, S)>>, "op must work as S(S, S)"); static_assert(std::is_convertible_v<decltype(e), std::function<S()>>, "e must work as S()"); static_assert( std::is_convertible_v<decltype(mapping), std::function<S(F, S)>>, "mapping must work as S(F, S)"); static_assert( std::is_convertible_v<decltype(composition), std::function<F(F, F)>>, "composition must work as F(F, F)"); static_assert(std::is_convertible_v<decltype(id), std::function<F()>>, "id must work as F()"); #else template <class S, S (*op)(S, S), S (*e)(), class F, S (*mapping)(F, S), F (*composition)(F, F), F (*id)()> struct lazy_segtree { #endif public: lazy_segtree() : lazy_segtree(0) {} explicit lazy_segtree(int n) : lazy_segtree(std::vector<S>(n, e())) {} explicit lazy_segtree(const std::vector<S>& v) : _n(int(v.size())) { size = (int)internal::bit_ceil((unsigned int)(_n)); log = internal::countr_zero((unsigned int)size); d = std::vector<S>(2 * size, e()); lz = std::vector<F>(size, id()); for (int i = 0; i < _n; i++) d[size + i] = v[i]; for (int i = size - 1; i >= 1; i--) { update(i); } } void set(int p, S x) { assert(0 <= p && p < _n); p += size; for (int i = log; i >= 1; i--) push(p >> i); d[p] = x; for (int i = 1; i <= log; i++) update(p >> i); } S get(int p) { assert(0 <= p && p < _n); p += size; for (int i = log; i >= 1; i--) push(p >> i); return d[p]; } S prod(int l, int r) { assert(0 <= l && l <= r && r <= _n); if (l == r) return e(); l += size; r += size; for (int i = log; i >= 1; i--) { if (((l >> i) << i) != l) push(l >> i); if (((r >> i) << i) != r) push((r - 1) >> i); } S sml = e(), smr = e(); while (l < r) { if (l & 1) sml = op(sml, d[l++]); if (r & 1) smr = op(d[--r], smr); l >>= 1; r >>= 1; } return op(sml, smr); } S all_prod() { return d[1]; } void apply(int p, F f) { assert(0 <= p && p < _n); p += size; for (int i = log; i >= 1; i--) push(p >> i); d[p] = mapping(f, d[p]); for (int i = 1; i <= log; i++) update(p >> i); } void apply(int l, int r, F f) { assert(0 <= l && l <= r && r <= _n); if (l == r) return; l += size; r += size; for (int i = log; i >= 1; i--) { if (((l >> i) << i) != l) push(l >> i); if (((r >> i) << i) != r) push((r - 1) >> i); } { int l2 = l, r2 = r; while (l < r) { if (l & 1) all_apply(l++, f); if (r & 1) all_apply(--r, f); l >>= 1; r >>= 1; } l = l2; r = r2; } for (int i = 1; i <= log; i++) { if (((l >> i) << i) != l) update(l >> i); if (((r >> i) << i) != r) update((r - 1) >> i); } } template <bool (*g)(S)> int max_right(int l) { return max_right(l, [](S x) { return g(x); }); } template <class G> int max_right(int l, G g) { assert(0 <= l && l <= _n); assert(g(e())); if (l == _n) return _n; l += size; for (int i = log; i >= 1; i--) push(l >> i); S sm = e(); do { while (l % 2 == 0) l >>= 1; if (!g(op(sm, d[l]))) { while (l < size) { push(l); l = (2 * l); if (g(op(sm, d[l]))) { sm = op(sm, d[l]); l++; } } return l - size; } sm = op(sm, d[l]); l++; } while ((l & -l) != l); return _n; } template <bool (*g)(S)> int min_left(int r) { return min_left(r, [](S x) { return g(x); }); } template <class G> int min_left(int r, G g) { assert(0 <= r && r <= _n); assert(g(e())); if (r == 0) return 0; r += size; for (int i = log; i >= 1; i--) push((r - 1) >> i); S sm = e(); do { r--; while (r > 1 && (r % 2)) r >>= 1; if (!g(op(d[r], sm))) { while (r < size) { push(r); r = (2 * r + 1); if (g(op(d[r], sm))) { sm = op(d[r], sm); r--; } } return r + 1 - size; } sm = op(d[r], sm); } while ((r & -r) != r); return 0; } private: int _n, size, log; std::vector<S> d; std::vector<F> lz; void update(int k) { d[k] = op(d[2 * k], d[2 * k + 1]); } void all_apply(int k, F f) { d[k] = mapping(f, d[k]); if (k < size) lz[k] = composition(f, lz[k]); } void push(int k) { all_apply(2 * k, lz[k]); all_apply(2 * k + 1, lz[k]); lz[k] = id(); } }; } // namespace atcoder #endif // ATCODER_LAZYSEGTREE_HPP struct MultiplicationNode { Int val; int count; static MultiplicationNode e() { return (MultiplicationNode){1, 0}; } static MultiplicationNode op(MultiplicationNode a, MultiplicationNode b) { return (MultiplicationNode){a.val * b.val, a.count + b.count}; } static MultiplicationNode mapping(Int f, MultiplicationNode x) { return (MultiplicationNode){x.val * f.pow(x.count), x.count}; } }; Int multiply(Int f, Int g) { return f * g; } Int add(Int f, Int g) { return f + g; } Int one() { return Int(1); } Int zero() { return Int(0); } using MultiplicationSegtree = atcoder::lazy_segtree< MultiplicationNode, MultiplicationNode::op, MultiplicationNode::e, Int, MultiplicationNode::mapping, multiply, one>; using AdditionSegtree = atcoder::lazy_segtree< Int, add, zero, Int, multiply, multiply, one>; int n; int a[500005]; int b[500005]; int rem[500005]; Int totkiri[500005],totkanan[500005]; Int two[50005]; MultiplicationSegtree segrem; AdditionSegtree segkanantambah; AdditionSegtree segkanankurang; AdditionSegtree segkiritambah; AdditionSegtree segkirikurang; int main() { scanf("%d",&n); two[0] = 1; FORN(i,1,n+2) two[i] = two[i - 1] * 2; segrem = MultiplicationSegtree( vector<MultiplicationNode>(n, (MultiplicationNode){2, 1})); // segkanantambah = segkanankurang = segkiritambah = segkirikurang = // AdditionSegtree(vector<Int>(n)); segkanantambah = segkanankurang = segkiritambah = segkirikurang = AdditionSegtree(vector<Int>(n, two[n])); REP(i,n) { // segkanantambah.set(i, two[n]); // segkanankurang.set(i, two[n - i - 1]); // segkiritambah.set(i, two[n]); // segkirikurang.set(i, two[i]); } REP(i,n) scanf("%d",&a[i]); REP(i,n) scanf("%d",&b[i]); vii angka; REP(i,n) { angka.pb(mp(a[i],i)); angka.pb(mp(b[i],i)); } SORT(angka); Int risan = 0; if (angka.back().fi == 2) { Int kiri = 1; Int kanan = two[n - 1]; REP(i,n) { risan += (kiri - 1) * (kanan - 1); kiri *= 2; kanan /= 2; } printf("%d\n",risan.get()); return 0; } REP(i,n) rem[i] = 2; FORD(i,SIZE(angka)-1,0) { int pos = angka[i].se; int h = angka[i].fi; // totkiri[0] = 1; // FOR(j,1,n) totkiri[j] = totkiri[j - 1] * rem[j - 1]; // totkanan[n - 1] = 1; // FORD(j,n-2,0) totkanan[j] = totkanan[j + 1] * rem[j + 1]; { risan += Int(h) / rem[pos] * segkanantambah.prod(pos + 1, n); risan -= Int(h) / rem[pos] * segkanankurang.prod(pos + 1, n); // FOR(j,pos+1,n) { // risan += totkiri[j] / rem[pos] * h * rem[j] * (two[n - j - 1] - totkanan[j]); // risan += Int(h) / rem[pos] * totkiri[j] * rem[j] * two[n - j - 1]; // risan -= Int(h) / rem[pos] * totkiri[j] * rem[j] * totkanan[j]; } } { risan += Int(h) / rem[pos] * segkiritambah.prod(0, pos); risan -= Int(h) / rem[pos] * segkirikurang.prod(0, pos); // FORD(j,pos-1,0) { // risan += totkanan[j] / rem[pos] * h * rem[j] * (two[j] - totkiri[j]); // risan += Int(h) / rem[pos] * totkanan[j] * rem[j] * two[j]; // risan -= Int(h) / rem[pos] * totkanan[j] * rem[j] * totkiri[j]; } } { // Int cur = 1; // REP(j,n) if (j != pos) cur *= rem[j]; // risan += h * cur; // cur = 1; // REP(j,pos) cur *= rem[j]; // risan += h * cur * totkanan[pos]; // cur = 1; // FORD(j,n-1,pos+1) cur *= rem[j]; // risan += h * cur * totkiri[pos]; // risan += h * totkiri[pos] * two[n - pos - 1]; // risan += h * two[pos] * totkanan[pos]; // risan -= h * totkiri[pos] * totkanan[pos]; risan += h * segrem.prod(0,pos).val * two[n - pos - 1]; risan += h * two[pos] * segrem.prod(pos+1,n).val; risan -= h * segrem.prod(0,pos).val * segrem.prod(pos+1,n).val; } if (rem[pos] == 2) { segrem.apply(pos,Int(1) / 2); segkanantambah.apply(pos, n, Int(1) / 2); // segkanankurang.apply(0, pos + 1, Int(1) / 2); segkanankurang.apply(0, n, Int(1) / 2); segkiritambah.apply(0, pos + 1, Int(1) / 2); segkirikurang.apply(0, n, Int(1) / 2); // segkirikurang.apply(pos, n, Int(1) / 2); } else if (rem[pos] == 1) { segrem.apply(pos,0); segkanantambah.apply(pos, n, 0); // segkanankurang.apply(0, pos + 1, 0); segkanankurang.apply(0, n, 0); segkiritambah.apply(0, pos + 1, 0); segkirikurang.apply(0, n, 0); // segkirikurang.apply(pos, n, 0); } --rem[pos]; } REP(i,n) risan -= (a[i] + b[i]) * two[n - 1]; printf("%d\n",risan.get()); }

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

Main.cpp: In function 'std::string uppercase(std::string)':
Main.cpp:33:29: warning: unnecessary parentheses in declaration of 'i' [-Wparentheses]
   33 | #define FOR(a,b,c) for (int (a)=(b);(a)<(c);++(a))
      |                             ^
Main.cpp:39:18: note: in expansion of macro 'FOR'
   39 | #define REP(i,n) FOR(i,0,n)
      |                  ^~~
Main.cpp:79:3: note: in expansion of macro 'REP'
   79 |   REP(i,n) if (s[i] >= 'a' && s[i] <= 'z') s[i] = s[i] - 'a' + 'A';
      |   ^~~
Main.cpp: In function 'std::string lowercase(std::string)':
Main.cpp:33:29: warning: unnecessary parentheses in declaration of 'i' [-Wparentheses]
   33 | #define FOR(a,b,c) for (int (a)=(b);(a)<(c);++(a))
      |                             ^
Main.cpp:39:18: note: in expansion of macro 'FOR'
   39 | #define REP(i,n) FOR(i,0,n)
      |                  ^~~
Main.cpp:85:3: note: in expansion of macro 'REP'
   85 |   REP(i,n) if (s[i] >= 'A' && s[i] <= 'Z') s[i] = s[i] - 'A' + 'a';
      |   ^~~
Main.cpp: In function 'int main()':
Main.cpp:34:30: warning: unnecessary parentheses in declaration of 'i' [-Wparentheses]
   34 | #define FORN(a,b,c) for (int (a)=(b);(a)<=(c);++(a))
      |                              ^
Main.cpp:549:3: note: in expansion of macro 'FORN'
  549 |   FORN(i,1,n+2) two[i] = two[i - 1] * 2;
      |   ^~~~
Main.cpp:33:29: warning: unnecessary parentheses in declaration of 'i' [-Wparentheses]
   33 | #define FOR(a,b,c) for (int (a)=(b);(a)<(c);++(a))
      |                             ^
Main.cpp:39:18: note: in expansion of macro 'FOR'
   39 | #define REP(i,n) FOR(i,0,n)
      |                  ^~~
Main.cpp:556:3: note: in expansion of macro 'REP'
  556 |   REP(i,n)
      |   ^~~
Main.cpp:33:29: warning: unnecessary parentheses in declaration of 'i' [-Wparentheses]
   33 | #define FOR(a,b,c) for (int (a)=(b);(a)<(c);++(a))
      |                             ^
Main.cpp:39:18: note: in expansion of macro 'FOR'
   39 | #define REP(i,n) FOR(i,0,n)
      |                  ^~~
Main.cpp:564:3: note: in expansion of macro 'REP'
  564 |   REP(i,n) scanf("%d",&a[i]);
      |   ^~~
Main.cpp:33:29: warning: unnecessary parentheses in declaration of 'i' [-Wparentheses]
   33 | #define FOR(a,b,c) for (int (a)=(b);(a)<(c);++(a))
      |                             ^
Main.cpp:39:18: note: in expansion of macro 'FOR'
   39 | #define REP(i,n) FOR(i,0,n)
      |                  ^~~
Main.cpp:565:3: note: in expansion of macro 'REP'
  565 |   REP(i,n) scanf("%d",&b[i]);
      |   ^~~
Main.cpp:33:29: warning: unnecessary parentheses in declaration of 'i' [-Wparentheses]
   33 | #define FOR(a,b,c) for (int (a)=(b);(a)<(c);++(a))
      |                             ^
Main.cpp:39:18: note: in expansion of macro 'FOR'
   39 | #define REP(i,n) FOR(i,0,n)
      |                  ^~~
Main.cpp:567:3: note: in expansion of macro 'REP'
  567 |   REP(i,n)
      |   ^~~
Main.cpp:33:29: warning: unnecessary parentheses in declaration of 'i' [-Wparentheses]
   33 | #define FOR(a,b,c) for (int (a)=(b);(a)<(c);++(a))
      |                             ^
Main.cpp:39:18: note: in expansion of macro 'FOR'
   39 | #define REP(i,n) FOR(i,0,n)
      |                  ^~~
Main.cpp:578:5: note: in expansion of macro 'REP'
  578 |     REP(i,n)
      |     ^~~
Main.cpp:33:29: warning: unnecessary parentheses in declaration of 'i' [-Wparentheses]
   33 | #define FOR(a,b,c) for (int (a)=(b);(a)<(c);++(a))
      |                             ^
Main.cpp:39:18: note: in expansion of macro 'FOR'
   39 | #define REP(i,n) FOR(i,0,n)
      |                  ^~~
Main.cpp:587:3: note: in expansion of macro 'REP'
  587 |   REP(i,n) rem[i] = 2;
      |   ^~~
Main.cpp:35:30: warning: unnecessary parentheses in declaration of 'i' [-Wparentheses]
   35 | #define FORD(a,b,c) for (int (a)=(b);(a)>=(c);--(a))
      |                              ^
Main.cpp:588:3: note: in expansion of macro 'FORD'
  588 |   FORD(i,SIZE(angka)-1,0)
      |   ^~~~
Main.cpp:33:29: warning: unnecessary parentheses in declaration of 'i' [-Wparentheses]
   33 | #define FOR(a,b,c) for (int (a)=(b);(a)<(c);++(a))
      |                             ^
Main.cpp:39:18: note: in expansion of macro 'FOR'
   39 | #define REP(i,n) FOR(i,0,n)
      |                  ^~~
Main.cpp:657:3: note: in expansion of macro 'REP'
  657 |   REP(i,n) risan -= (a[i] + b[i]) * two[n - 1];
      |   ^~~
Main.cpp:546:8: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  546 |   scanf("%d",&n);
      |   ~~~~~^~~~~~~~~
Main.cpp:564:17: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  564 |   REP(i,n) scanf("%d",&a[i]);
      |            ~~~~~^~~~~~~~~~~~
Main.cpp:565:17: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  565 |   REP(i,n) scanf("%d",&b[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...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...