Submission #994625

#TimeUsernameProblemLanguageResultExecution timeMemory
994625jonathanirvingsTrains (BOI24_trains)C++17
100 / 100
737 ms80720 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) #ifndef ATCODER_FENWICKTREE_HPP #define ATCODER_FENWICKTREE_HPP 1 #include <cassert> #include <vector> #ifndef ATCODER_INTERNAL_TYPE_TRAITS_HPP #define ATCODER_INTERNAL_TYPE_TRAITS_HPP 1 #include <cassert> #include <numeric> #include <type_traits> namespace atcoder { namespace internal { #ifndef _MSC_VER template <class T> using is_signed_int128 = typename std::conditional<std::is_same<T, __int128_t>::value || std::is_same<T, __int128>::value, std::true_type, std::false_type>::type; template <class T> using is_unsigned_int128 = typename std::conditional<std::is_same<T, __uint128_t>::value || std::is_same<T, unsigned __int128>::value, std::true_type, std::false_type>::type; template <class T> using make_unsigned_int128 = typename std::conditional<std::is_same<T, __int128_t>::value, __uint128_t, unsigned __int128>; template <class T> using is_integral = typename std::conditional<std::is_integral<T>::value || is_signed_int128<T>::value || is_unsigned_int128<T>::value, std::true_type, std::false_type>::type; template <class T> using is_signed_int = typename std::conditional<(is_integral<T>::value && std::is_signed<T>::value) || is_signed_int128<T>::value, std::true_type, std::false_type>::type; template <class T> using is_unsigned_int = typename std::conditional<(is_integral<T>::value && std::is_unsigned<T>::value) || is_unsigned_int128<T>::value, std::true_type, std::false_type>::type; template <class T> using to_unsigned = typename std::conditional< is_signed_int128<T>::value, make_unsigned_int128<T>, typename std::conditional<std::is_signed<T>::value, std::make_unsigned<T>, std::common_type<T>>::type>::type; #else template <class T> using is_integral = typename std::is_integral<T>; template <class T> using is_signed_int = typename std::conditional<is_integral<T>::value && std::is_signed<T>::value, std::true_type, std::false_type>::type; template <class T> using is_unsigned_int = typename std::conditional<is_integral<T>::value && std::is_unsigned<T>::value, std::true_type, std::false_type>::type; template <class T> using to_unsigned = typename std::conditional<is_signed_int<T>::value, std::make_unsigned<T>, std::common_type<T>>::type; #endif template <class T> using is_signed_int_t = std::enable_if_t<is_signed_int<T>::value>; template <class T> using is_unsigned_int_t = std::enable_if_t<is_unsigned_int<T>::value>; template <class T> using to_unsigned_t = typename to_unsigned<T>::type; } // namespace internal } // namespace atcoder #endif // ATCODER_INTERNAL_TYPE_TRAITS_HPP namespace atcoder { // Reference: https://en.wikipedia.org/wiki/Fenwick_tree template <class T> struct fenwick_tree { using U = internal::to_unsigned_t<T>; public: fenwick_tree() : _n(0) {} explicit fenwick_tree(int n) : _n(n), data(n) {} void add(int p, T x) { assert(0 <= p && p < _n); p++; while (p <= _n) { data[p - 1] += U(x); p += p & -p; } } T sum(int l, int r) { assert(0 <= l && l <= r && r <= _n); return sum(r) - sum(l); } private: int _n; std::vector<U> data; U sum(int r) { U s = 0; while (r > 0) { s += data[r - 1]; r -= r & -r; } return s; } }; } // namespace atcoder #endif // ATCODER_FENWICKTREE_HPP 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>; using BinomCoeff = ModBinomCoeff<Mod>; using Fenwick = atcoder::fenwick_tree<Int>; int LIMIT = 200; int n; int d[100005]; int x[100005]; Int dp[100005]; vector<vector<Fenwick>> fenwick; int main() { scanf("%d",&n); REP(i,n) scanf("%d %d",&d[i],&x[i]); fenwick.resize(LIMIT); FOR(delta,1,LIMIT) { fenwick[delta].resize(delta); REP(i,delta) fenwick[delta][i] = Fenwick(n / delta + 3); } FORD(i,n-1,0) { // debug("%d\n",i); dp[i] = 1; if (d[i] >= LIMIT) { FORN(t,1,x[i]) { if (i + d[i] * t >= n) break; dp[i] += dp[i + d[i] * t]; } } else if (d[i] > 0) { int l = i / d[i]; int r = min(n / d[i] + 3, l + x[i] + 1); dp[i] += fenwick[d[i]][i % d[i]].sum(l,r); } FOR(delta,1,LIMIT) fenwick[delta][i % delta].add(i / delta,dp[i]); } printf("%d\n",dp[0].get()); }

Compilation message (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: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:386:3: note: in expansion of macro 'REP'
  386 |   REP(i,n) scanf("%d %d",&d[i],&x[i]);
      |   ^~~
Main.cpp:33:29: warning: unnecessary parentheses in declaration of 'delta' [-Wparentheses]
   33 | #define FOR(a,b,c) for (int (a)=(b);(a)<(c);++(a))
      |                             ^
Main.cpp:388:3: note: in expansion of macro 'FOR'
  388 |   FOR(delta,1,LIMIT)
      |   ^~~
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:391:5: note: in expansion of macro 'REP'
  391 |     REP(i,delta) fenwick[delta][i] = Fenwick(n / delta + 3);
      |     ^~~
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:393:3: note: in expansion of macro 'FORD'
  393 |   FORD(i,n-1,0)
      |   ^~~~
Main.cpp:34:30: warning: unnecessary parentheses in declaration of 't' [-Wparentheses]
   34 | #define FORN(a,b,c) for (int (a)=(b);(a)<=(c);++(a))
      |                              ^
Main.cpp:399:7: note: in expansion of macro 'FORN'
  399 |       FORN(t,1,x[i])
      |       ^~~~
Main.cpp:33:29: warning: unnecessary parentheses in declaration of 'delta' [-Wparentheses]
   33 | #define FOR(a,b,c) for (int (a)=(b);(a)<(c);++(a))
      |                             ^
Main.cpp:410:5: note: in expansion of macro 'FOR'
  410 |     FOR(delta,1,LIMIT) fenwick[delta][i % delta].add(i / delta,dp[i]);
      |     ^~~
Main.cpp:385:8: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  385 |   scanf("%d",&n);
      |   ~~~~~^~~~~~~~~
Main.cpp:386:17: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  386 |   REP(i,n) scanf("%d %d",&d[i],&x[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...