[Codeforces 897E. Willem, Chtholly and Seniorious]概率隨機+set
分類:math
probability
random
1. 題目鏈接
[Codeforces 897E. Willem, Chtholly and Seniorious]
2. 題意描述
有一個序列
操作1:將
操作2:將
操作3:求
操作4:求
注意:序列
數據範圍:
3. 解題思路
上面四種操作,出現的概率都是
假如用線段來描述序列合併到線段數目小於某一個值的次數
的數學期望。
但是自己打印了一下,大概線段數目
小於200
。
然後,知道了這種性質之後,就可以用
所以說,學好概率論太重要啦!
4. 實現代碼
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
const int inf = 0x3f3f3f3f;
const ll infl = 0x3f3f3f3f3f3f3f3fLL;
template<typename T> inline void umax(T &a, T b) { a = max(a, b); }
template<typename T> inline void umin(T &a, T b) { a = min(a, b); }
void debug() { cout << endl; }
template<typename T, typename ...R> void debug (T f, R ...r) { cout << "[" << f << "]"; debug (r...); }
const int MAXN = 100005;
ll n, m, seed, vmax, a[MAXN];
ll rnd() {
ll ret = seed;
seed = (seed * 7 + 13) % 1000000007;
return ret;
}
struct Line {
pii itv; ll val;
Line() {}
Line(pii itv, ll val) : itv(itv), val(val) {}
bool operator < (const Line& line) const {
return itv < line.itv;
}
};
bool cmp_val(const Line& l1, const Line& l2) {
return l1.val < l2.val;
}
set<Line> st;
set<Line>::iterator it, it1, it2;
void oper1(int l, int r, ll x) {
// [it1, it2)
it1 = st.upper_bound(Line(pii(l, inf), 0ll)); --it1;
it2 = st.upper_bound(Line(pii(r, inf), 0ll));
vector<Line> buf;
for (it = it1; it != it2; ++it) {
if ((it->itv).first > r) break;
buf.push_back(*it);
}
st.erase(it1, it2);
if (buf[0].itv.first < l) {
st.insert(Line(pii(buf[0].itv.first, l - 1), buf[0].val));
buf[0].itv.first = l;
}
int sz = buf.size();
if (buf[sz - 1].itv.second > r) {
st.insert(Line(pii(r + 1, buf[sz - 1].itv.second), buf[sz - 1].val));
buf[sz - 1].itv.second = r;
}
for (Line& line : buf) {
line.val += x;
st.insert(line);
}
// for(int i = l; i <= r; ++i) a[i] += x;
}
void oper2(int l, int r, ll x) {
// [it1, it2)
it1 = st.upper_bound(Line(pii(l, inf), 0ll)); --it1;
it2 = st.upper_bound(Line(pii(r, inf), 0ll));
vector<Line> buf;
for (it = it1; it != it2; ++it) {
if ((it->itv).first > r) break;
buf.push_back(*it);
}
st.erase(it1, it2);
if (buf[0].itv.first < l && buf[0].val != x) {
st.insert(Line(pii(buf[0].itv.first, l - 1), buf[0].val));
buf[0].itv.first = l;
}
int sz = buf.size();
if (buf[sz - 1].itv.second > r && buf[sz - 1].val != x) {
st.insert(Line(pii(r + 1, buf[sz - 1].itv.second), buf[sz - 1].val));
buf[sz - 1].itv.second = r;
}
st.insert(Line(pii(buf[0].itv.first, buf[sz - 1].itv.second), x));
// for(int i = l; i <= r; ++i) a[i] = x;
}
ll oper3(int l, int r, ll x) {
// [it1, it2)
it1 = st.upper_bound(Line(pii(l, inf), 0ll)); --it1;
it2 = st.upper_bound(Line(pii(r, inf), 0ll));
vector<Line> buf;
for (it = it1; it != it2; ++it) {
if ((it->itv).first > r) break;
buf.push_back(*it);
}
if (buf[0].itv.first < l) {
buf[0].itv.first = l;
}
int sz = buf.size();
if (buf[sz - 1].itv.second > r) {
buf[sz - 1].itv.second = r;
}
sort(buf.begin(), buf.end(), cmp_val);
ll w = 0;
for (Line& line : buf) {
w += (line.itv.second - line.itv.first + 1);
if (w >= x) return line.val;
}
return -1;
}
ll qpow(ll a, ll b, ll mod) {
ll ret = 1;
a = a % mod; // notice here!!!
while (b > 0) {
if (b & 1) ret = ret * a % mod;
a = a * a % mod;
b >>= 1;
}
return ret;
}
ll oper4(int l, int r, ll x, ll y) {
// [it1, it2)
it1 = st.upper_bound(Line(pii(l, inf), 0ll)); --it1;
it2 = st.upper_bound(Line(pii(r, inf), 0ll));
vector<Line> buf;
for (it = it1; it != it2; ++it) {
if ((it->itv).first > r) break;
buf.push_back(*it);
}
if (buf[0].itv.first < l) {
buf[0].itv.first = l;
}
int sz = buf.size();
if (buf[sz - 1].itv.second > r) {
buf[sz - 1].itv.second = r;
}
ll ret = 0;
for (Line& line : buf) {
int w = (line.itv.second - line.itv.first + 1);
ret += (ll)w * qpow(line.val, x, y) % y;
ret %= y;
}
return ret;
}
int main() {
#ifdef ___LOCAL_WONZY___
freopen("input.txt", "r", stdin);
freopen("output.txt", "w+", stdout);
#endif // ___LOCAL_WONZY___
cin >> n >> m >> seed >> vmax;
for (int i = 1; i <= n; ++i) a[i] = (rnd() % vmax) + 1;
st.clear();
for (int i = 1; i <= n; ++i) {
int j = i;
while (j + 1 <= n && a[i] == a[j + 1]) ++j;
st.insert(Line(pii(i, j), a[i]));
i = j;
}
int op, l, r; ll x, y;
int cnt = 0;
for (int i = 1; i <= m; ++i) {
op = rnd() % 4 + 1;
l = rnd() % n + 1;
r = rnd() % n + 1;
if (l > r) swap(l, r);
if (op == 3) x = (rnd() % (r - l + 1)) + 1;
else x = (rnd() % vmax) + 1;
if (op == 4) y = (rnd() % vmax) + 1;
// debug(op, l, r, x, y);
if (op == 1) oper1(l, r, x);
else if (op == 2) oper2(l, r, x);
else if (op == 3) {
ll ret = oper3(l, r, x);
cout << ret << endl;
} else {
ll ret = oper4(l, r, x, y);
cout << ret << endl;
}
}
#ifdef ___LOCAL_WONZY___
cout << "Time elapsed: " << 1.0 * clock() / CLOCKS_PER_SEC * 1000 << "ms." << endl;
#endif // ___LOCAL_WONZY___
return 0;
}