結果
問題 |
No.3265 地元に帰れば天才扱い!
|
ユーザー |
|
提出日時 | 2025-09-29 00:08:24 |
言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 1,708 ms / 2,500 ms |
コード長 | 8,085 bytes |
コンパイル時間 | 2,169 ms |
コンパイル使用メモリ | 211,468 KB |
実行使用メモリ | 17,720 KB |
最終ジャッジ日時 | 2025-09-29 00:09:10 |
合計ジャッジ時間 | 39,628 ms |
ジャッジサーバーID (参考情報) |
judge3 / judge2 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 4 |
other | AC * 21 |
ソースコード
#include<bits/stdc++.h> //入力系 #define cinll(...) ll __VA_ARGS__; input(__VA_ARGS__); #define cinint(...) int __VA_ARGS__; input(__VA_ARGS__); #define cinstr(...) string __VA_ARGS__; input(__VA_ARGS__); #define cinchar(...) char __VA_ARGS__; input(__VA_ARGS__); #define cindouble(...) double __VA_ARGS__; input(__VA_ARGS__); #define cinvll(a,n) vll a(n); rep(i,n) cin>>a[i]; #define cinvvll(a,n,m) vvll a(n,vll(m)); rep(i,n) rep(j,m) cin>>a[i][j]; #define cinvs(a,n) vs a(n); rep(i,n) cin>>a[i]; #define cinvpll(a,n) vpll a(n); rep(i,n) cin>>a[i].fst>>a[i].snd; //繰り返し系 #define rep1(n) for(ll i=0;i<n;i++) #define rep2(i,n) for(ll i=0;i<n;i++) #define rep3(i,a,n) for(ll i=a;i<n;i++) #define rep4(i,a,n,b) for(ll i=a;i<n;i+=b) #define overload4(a,b,c,d,e,...) e #define rep(...) overload4(__VA_ARGS__,rep4,rep3,rep2,rep1)(__VA_ARGS__) #define mrep1(n) for(ll i=n;i>=0;i--) #define mrep2(i,n) for(ll i=n;i>=0;i--) #define mrep3(i,n,a) for(ll i=n;i>=a;i--) #define mrep4(i,n,a,b) for(ll i=n;i>=a;i-=b) #define mrep(...) overload4(__VA_ARGS__,mrep4,mrep3,mrep2,mrep1)(__VA_ARGS__) //iterator系 #define all(a) a.begin(),a.end() #define rall(a) a.rbegin(),a.rend() //書くのが長いやつ #define fst first #define snd second #define cvvll1(name,a,b) vvll name(a, vll(b)) #define cvvll2(name,a,b,c) vvll name(a, vll(b,c)) #define cvvlloverload2(name,a,b,c,d,...) d #define make_vvll(...) cvvlloverload2(__VA_ARGS__,cvvll2,cvvll1)(__VA_ARGS__) using namespace std; //型系 using ll = long long; using vll = vector<long long>; using vvll = vector<vector<long long>>; using vi = vector<int>; using vvi = vector<vector<int>>; using vb = vector<bool>; using vvb = vector<vector<bool>>; using vd = vector<double>; using vvd = vector<vector<double>>; using vc = vector<char>; using vvc = vector<vector<char>>; using vs = vector<string>; using pll = pair<long long,long long>; using pi = pair<int,int>; using pd = pair<double,double>; using sll = set<long long>; using vsll = vector<set<long long>>; using vpll = vector<pair<long long,long long>>; using vpi = vector<pi>; using vpd = vector<pair<double, double>>; using vvpll = vector<vector<pair<long long, long long>>>; #define vmll vector<mll> #define vvmll vector<vector<mll>> const ll mod = 998244353LL; //const ll mod = 1000000007LL; const ll inf = 1300100100100100100LL; const double PI=3.1415926535897932384626433832795028841971; //表示 #define overload1(a,b,NAME,...) NAME #define coutYesReturn() do {coutYes(); return 0; } while(0) #define coutYesReturnIf(a) do { if(a){ coutYesReturn(); }} while(0) #define coutNoReturn() do {coutNo(); return 0;} while(0) #define coutNoReturnIf(a) do {if(a){ coutNoReturn(); }} while(0) #define coutReturnIf(a,s) do{if(a){cout<<s<<endl; return 0;}}while(0) template<typename... T> void coutll(T... a){ ((cout << a <<" "),...) << endl; } void coutvll(vll &a){ rep(i,a.size()) cout<<a[i]<<" "; cout<<endl; } void coutvll(string name, vll &a){ cout<<name<<":"; coutvll(a); } void coutvlln(vll &a){ rep(i,a.size()) cout<<a[i]<<endl; } void coutYes(){ cout<<"Yes"<<endl; } void coutNo(){ cout<<"No"<<endl; } void coutYesNo(bool a){ cout<<(a?"Yes":"No")<<endl; } void coutIf(bool a, string s, string t){ cout<<(a?s:t)<<endl; } //入力 template<class... T> void input(T&... a){ (cin >> ... >> a); } //複数ソート template<class... T> void sorts(vector<T>&... a){ (sort(all(a)),...); } //便利関数 template<typename T> bool chmax(T &a, T b){ if(a < b) {a = b; return true;} return false; } template<typename T> bool chmin(T &a, T b){ if(a > b) {a = b; return true;} return false; } //配列表示用 template <typename T> std::ostream& operator<<(std::ostream& os, const std::vector<T>& vec) { rep(i,vec.size()) os << vec[i] << (i==(ll)vec.size()-1?"":" "); return os; } //コンストラクタ 関数ポインタの部分は普通に関数名書くだけでOK //SegmentTree<T>(vector<T>&,T (*f)(T,T),T ide) //SegmentTree<T>(int n,T (*f)(T,T),T ide) //関数 //Change(int,T) //get(int,int)閉区間 template<typename T> class SegmentTree{ int n; T ident; vector<T> array; T (*op)(T,T); public: SegmentTree(vector<T> &v,T (*f)(T,T),T ide){ int sz = v.size(); this->n = 1; while(n < sz) n *= 2; this->array = vector<T>(2*this->n-1,ide); this->ident = ide; this->op = f; for(int i=0;i<sz;i++) change(i,v[i]); } SegmentTree(int a,T (*f)(T,T),T ide){ this->n = 1; while(n < a) n*= 2; this->array = vector<T>(2*this->n-1,ide); this->ident = ide; this->op = f; } SegmentTree(){} int l_child(int i){ return i*2+1; } int r_child(int i){ return i*2+2; } int get_parent(int i){ return (i%2 == 0) ? (i/2-1):(i/2); } void change(int i,T v){ int ind = this->array.size()/2+i; this->array[ind] = v; int parent = get_parent(ind); while(parent != -1){ this->array[parent] = op(this->array[l_child(parent)],this->array[r_child(parent)]); parent = get_parent(parent); } } T get(int l,int r,int k=0,int nowL=-1,int nowR=-1){ if(k == 0){ nowL = 0; nowR = this->array.size()/2; } if(r < nowL || nowR < l) return this->ident; if(l <= nowL && nowR <= r) return this->array[k]; T vl = get(l,r,l_child(k),nowL,(nowL+nowR)/2); T vr = get(l,r,r_child(k),(nowL+nowR)/2+1,nowR); return op(vl,vr); } }; struct S { ll a, l, r; }; int main(){ cinll(n, m); SegmentTree<ll> st_sum(m, [](ll a, ll b){ return a+b; }, 0); SegmentTree<ll> st_range(m+1, [](ll a, ll b){ return a+b; }, 0); vector<S> ss(n); // 元々住んでいる場所 vll live(n); rep(i,n) live[i] = i; rep(i,n){ cinll(a, l, r); a; l--; r--; st_sum.change(i, a); st_range.change(l, st_range.get(l, l)+1); st_range.change(r+1, st_range.get(r+1, r+1)-1); ss[i] = {a, l, r}; } // cout << "st_sum :"; // rep(i,m) cout << st_sum.get(i,i) << " "; // cout << endl; // 現状の総和を求める ll ans = 0; rep(i,n){ //cout << "i:"<<i<<" "<<(ss[i].r-ss[i].l+1)*ss[i].a<<" "<<st_sum.get(ss[i].l, ss[i].r); ans += (ss[i].r-ss[i].l+1) * ss[i].a; ans -= st_sum.get(ss[i].l, ss[i].r); //cout << endl; } //cout << ans << endl; cinll(q); while(q--){ cinll(x, y, u, v); x--; y--; u--; v--; // まずはlive[x]からxを消す //cout << "消すぜ " << (ss[x].r-ss[x].l+1) * ss[x].a <<" "<< st_sum.get(ss[x].l, ss[x].r)<<" "<<st_range.get(0, live[x]) * ss[x].a<< endl; ans -= (ss[x].r-ss[x].l+1) * ss[x].a; ans += st_sum.get(ss[x].l, ss[x].r); ans += st_range.get(0, live[x]) * ss[x].a; if(ss[x].l <= live[x] && live[x] <= ss[x].r) ans -= ss[x].a; st_sum.change(live[x], 0); st_range.change(ss[x].l, st_range.get(ss[x].l, ss[x].l)-1); st_range.change(ss[x].r+1, st_range.get(ss[x].r+1, ss[x].r+1)+1); // yに引っ越す live[x] = y; ss[x].l = u; ss[x].r = v; st_sum.change(live[x], ss[x].a); st_range.change(ss[x].l, st_range.get(ss[x].l, ss[x].l)+1); st_range.change(ss[x].r+1, st_range.get(ss[x].r+1, ss[x].r+1)-1); //cout << "増やすぜ " << (ss[x].r-ss[x].l+1) * ss[x].a <<" "<< st_sum.get(ss[x].l, ss[x].r)<<" "<<st_range.get(0, live[x]) * ss[x].a<< endl; ans += (ss[x].r - ss[x].l + 1) * ss[x].a; ans -= st_sum.get(ss[x].l, ss[x].r); ans -= st_range.get(0, live[x]) * ss[x].a; if(ss[x].l <= live[x] && live[x] <= ss[x].r) ans += ss[x].a; // cout << "st_sum :"; // rep(i,m) cout << st_sum.get(i,i) << " "; // cout << endl; // rep(i,n){ // cout << "i:"<<i<<" "<<(ss[i].r-ss[i].l+1)*ss[i].a<<" "<<st_sum.get(ss[i].l, ss[i].r); // cout << endl; // } cout << ans << endl; } return 0; }