結果
問題 | No.833 かっこいい電車 |
ユーザー |
![]() |
提出日時 | 2019-05-24 21:50:52 |
言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 565 ms / 2,000 ms |
コード長 | 4,703 bytes |
コンパイル時間 | 1,796 ms |
コンパイル使用メモリ | 133,756 KB |
最終ジャッジ日時 | 2025-01-07 03:58:14 |
ジャッジサーバーID (参考情報) |
judge3 / judge2 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 2 |
other | AC * 30 |
ソースコード
#include<iostream>#include<iomanip>#include<vector>#include<algorithm>#include<set>#include<map>#include<unordered_map>#include<stack>#include<queue>#include<math.h>#include<functional>#include<bitset>#include<cassert>#include<random>using namespace std;using lint = long long;using ld = long double;using pint = pair<int, int>;using plint = pair<lint, lint>;#define INF 1000000000LL#define EPS 1e-12#define FOR(i,n,m) for(lint i=n;i<(int)m;i++)#define REP(i,n) FOR(i,0,n)#define DUMP(a) REP(d,a.size()){cout<<a[d];if(d!=a.size()-1)cout<<" ";else cout<<endl;}#define ALL(v) v.begin(),v.end()#define UNIQUE(v) sort(ALL(v));v.erase(unique(ALL(v)),v.end());#define pb push_back#include <cstdint>using i64 = std::int_fast64_t;const static i64 mod = 1000000007;struct mint {i64 n;public:mint(const i64 n = 0) : n((n % mod + mod) % mod) {}mint pow(int m) const {i64 a = n, r = 1;while(m > 0) {if(m & 1) { r *= a; r %= mod; }a = (a * a) % mod; m /= 2;}return mint(r);}mint &operator++() { *this += 1; return *this; }mint &operator--() { *this -= 1; return *this; }mint operator++(int) { mint ret = *this; *this += 1; return ret; }mint operator--(int) { mint ret = *this; *this -= 1; return ret; }mint operator~() const { return (this -> pow(mod - 2)); } // inversefriend bool operator==(const mint& lhs, const mint& rhs) {return lhs.n == rhs.n;}friend bool operator<(const mint& lhs, const mint& rhs) {return lhs.n < rhs.n;}friend bool operator>(const mint& lhs, const mint& rhs) {return lhs.n > rhs.n;}friend mint &operator+=(mint& lhs, const mint& rhs) {lhs.n += rhs.n;if (lhs.n >= mod) lhs.n -= mod;return lhs;}friend mint &operator-=(mint& lhs, const mint& rhs) {lhs.n -= rhs.n;if (lhs.n < 0) lhs.n += mod;return lhs;}friend mint &operator*=(mint& lhs, const mint& rhs) {lhs.n = (lhs.n * rhs.n) % mod;return lhs;}friend mint &operator/=(mint& lhs, const mint& rhs) {lhs.n = (lhs.n * (~rhs).n) % mod;return lhs;}friend mint operator+(const mint& lhs, const mint& rhs) {return mint(lhs.n + rhs.n);}friend mint operator-(const mint& lhs, const mint& rhs) {return mint(lhs.n - rhs.n);}friend mint operator*(const mint& lhs, const mint& rhs) {return mint(lhs.n * rhs.n);}friend mint operator/(const mint& lhs, const mint& rhs) {return mint(lhs.n * (~rhs).n);}};istream& operator>>(istream& is, mint& m) { is >> m.n; return is; }ostream& operator<<(ostream& os, mint& m) { os << m.n; return os; }template <typename T>class SegTree {private:int n;const function<T(T, T)> op; // 演算const T ie; // 演算の単位元vector<T> seq;public:/// op: 演算, ie: 演算の単位元SegTree(int _n, function<T(T, T)> op, const T ie) : op(op), ie(ie) {n = 1;while(n < _n) n *= 2;seq.resize(2 * n - 1);for(int i = 0; i < 2 * n - 1; i++) seq[i] = ie;}/// k 番目(0-indexed)の要素を e で更新void update(int k, const T e) {k += n - 1;seq[k] = e;while(k > 0) {k = (k - 1) / 2;seq[k] = op(seq[k * 2 + 1], seq[k * 2 + 2]);}}// k 番目(0-indexed)の要素を取得T get(int k) {k += n - 1;return seq[k];}/// [a, b) 番目(0-indexed)の要素全体の演算結果を返すT query(int a, int b, int k = 0, int l = 0, int r = -1) {if(r == -1) r = n;if(r <= a || b <= l) return ie;if(a <= l && r <= b) return seq[k];T vl = query(a, b, k * 2 + 1, l, (l + r) / 2);T vr = query(a, b, k * 2 + 2, (l + r) / 2, r);return op(vl, vr);}};// [Range Sum Query] rsq(n, [] (ll a, ll b) { return a + b; }, 0)// [Range Max Query] rMq(n, [] (ll a, ll b) { return max(a, b); }, -1e18)// [Range Min Query] rmq(n, [] (ll a, ll b) { return min(a, b); }, 1e18)int main() {ios::sync_with_stdio(false);cin.tie(0);int n, q;cin >> n >> q;SegTree<lint> rsq1(n, [] (lint a, lint b) { return a + b; }, 0);SegTree<lint> rsq2(n - 1, [] (lint a, lint b) { return a + b; }, 0);REP(i, n) {lint a;cin >> a;rsq1.update(i, a);}REP(i, q) {int qq;lint x;cin >> qq >> x;x--;if(qq == 1) {rsq2.update(x, 1);}else if(qq == 2) {rsq2.update(x, 0);}else if(qq == 3) {rsq1.update(x, rsq1.get(x) + 1);} else {int ng = -1, ok = x;while(abs(ok - ng) > 1) {int m = (ng + ok) / 2;if(rsq2.query(m, x) == x - m) ok = m;else ng = m;}int l = ok;ok = x; ng = n;while(abs(ok - ng) > 1) {int m = (ng + ok) / 2;if(rsq2.query(x, m) == m - x) ok = m;else ng = m;}int r = ok;cout << rsq1.query(l, r + 1) << endl;}}return 0;}/* --------------------------------------- */