This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
//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 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... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |