Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // trace works only with c++ 14
- #include<bits/stdc++.h>
- using namespace std;
- //#pragma comment (linker, "/STACK:256000000")
- #define TRACE
- #ifdef TRACE
- #define trace(...) __f(#__VA_ARGS__, __VA_ARGS__)
- template <typename Arg1>
- void __f(const char* name, Arg1&& arg1) {
- cerr << name << " : " << arg1 << endl;
- }
- template <typename Arg1, typename... Args>
- void __f(const char* names, Arg1&& arg1, Args&&... args) {
- const char* comma = strchr(names + 1, ',');
- cerr.write(names, comma - names) << " : " << arg1<<" | ";
- __f(comma+1, args...);
- }
- #else
- #define trace(...)
- #endif
- #define all(a) a.begin(), a.end()
- #define endl '\n'
- #define mp make_pair
- #define pb push_back
- #define f first
- #define s second
- #define boost ios_base::sync_with_stdio(false);
- #define FOR(i, a, b) for (int i = (a); i < (b); ++i)
- #define REP(i, n) FOR(i, 0, n)
- typedef long long llint;
- typedef long long ll ;
- typedef pair<int, int> pii;
- typedef vector<int> vi;
- typedef vector<pii> vii;
- const int mod = 1e9 + 7 ;
- ll powmod(ll a,ll b) {ll res=1;if(a>=mod)a%=mod;for(;b;b>>=1){if(b&1)res=res*a;if(res>=mod)res%=mod;a=a*a;if(a>=mod)a%=mod;}return res;}
- ll gcd(ll a , ll b){return a==0?b:gcd(b%a,a);}
- /*---------------------------------------------------------------------------------------------------------------------*/
- const int maxn = 800000 + 100;
- const int inf = INT_MAX;
- ll tree[maxn * 4];
- ll w[maxn], d[maxn], z[maxn], s[maxn], g[maxn][3];
- ll aw, bw, ad, bd, as, bs, s1, d1, w1;
- ll n, m;
- int MOD = 1000 * 1000 * 1000;
- #define front 2
- #define back 0
- #define same 1
- void build(int node, int a, int b)
- {
- if(a == b)
- {
- tree[node] = 1;
- return;
- }
- build(node * 2, a, (a + b) / 2);
- build(node * 2 + 1, (a + b) / 2 + 1, b);
- tree[node] = 1;
- }
- ll query(int node, int a, int b, int i, int j)
- {
- if(a > b || a > j || b < i || j < i)
- return 1;
- if(a >= i && b <= j)
- return tree[node];
- ll ret = query(node * 2, a, (a + b) / 2, i, j) * query(node * 2 + 1, (a + b) / 2 + 1, b, i, j);
- if(ret >= mod)
- ret %= mod;
- return ret;
- }
- ll upd(int node, int a, int b, int i)
- {
- if(a > b)
- return 1;
- if( a > i || b < i)
- return tree[node];
- if(a == b)
- {
- tree[node] = g[a][1];
- //trace(tree[node], a, b, i);
- return tree[node];
- }
- ll ret1 = upd(node * 2, a, (a + b) / 2, i) * upd(node * 2 + 1, (a + b) / 2 + 1, b, i);
- if(ret1 >= mod)
- ret1 %= mod;
- ll ret2 = query(1, 1, n, a, (a + b) / 2 - 1) * query(1, 1, n, (a + b) / 2 + 2, b);
- if(ret2 >= mod)
- ret2 %= mod;
- ret2 = ret2 * g[(a + b) / 2][front];
- if(ret2 >= mod)
- ret2 %= mod;
- ret2 = ret2 * g[(a + b) / 2 + 1][back];
- if(ret2 >= mod)
- ret2 %= mod;
- //trace(ret1, ret2, a, b, i);
- ret1 += ret2;
- if(ret1 >= mod)
- ret1 -= mod;
- return tree[node] = ret1;
- }
- int main() {
- freopen("in.txt","r",stdin);
- freopen("out.txt","w",stdout);
- boost;cin.tie(0);
- int t, tt = 0, i;
- cin >> t;
- while(t--)
- {
- tt++;
- cout << "Case #" << tt << ": ";
- cin >> n >> m;
- cin >> w1 >> aw >> bw;
- cin >> d1 >> ad >> bd;
- cin >> s1 >> as >> bs;
- w[1] = w1;
- d[1] = d1;
- s[1] = s1;
- for(i = 2; i <= m; i++)
- w[i] = (w[i - 1] * aw + bw) % n + 1;
- for(i = 2; i <= m; i++)
- d[i] = (ad * d[i - 1] + bd) % 3;
- for(i = 1; i <= m; i++)
- z[i] = max(1LL, min(n, w[i] + d[i] - 1));
- for(i = 2; i <= m; i++)
- s[i] = (as * s[i - 1] + bs) % MOD + 1;
- build(1, 1, n);
- ll ans = 0;
- for(i = 0; i <= n + 5; i++)
- {
- g[i][same] = g[i][front] = g[i][back] = 0;
- if(i >= 1 && i <= n)
- g[i][same] = 1;
- }
- for(i = 1; i <= m; i++)
- {
- g[w[i]][z[i] - w[i] + 1] += s[i];
- if(g[w[i]][z[i] - w[i] + 1] >= mod)
- g[w[i]][z[i] - w[i] + 1] -= mod;
- upd(1, 1, n, w[i]);
- ans += tree[1];
- if(ans >= mod)
- ans -= mod;
- }
- cout << ans << endl;
- }
- return 0;
- }
Add Comment
Please, Sign In to add comment