Submission #236910

#TimeUsernameProblemLanguageResultExecution timeMemory
236910rajarshi_basuFire (JOI20_ho_t5)C++14
100 / 100
651 ms52684 KiB
#include <stdio.h> #include <stdlib.h> #include <iostream> #include <vector> #include <algorithm> #include <fstream> #include <queue> #include <deque> #include <iomanip> #include <cmath> #include <set> #include <stack> #include <map> #include <unordered_map> #define FOR(i,n) for(int i=0;i<n;i++) #define FORE(i,a,b) for(int i=a;i<=b;i++) #define ll long long #define ld long double //#define int ll //#define int short #define vi vector<int> #define pb push_back #define ff first #define ss second #define ii pair<int,int> #define iii pair<int,ii> #define iiii pair<iii,int> #define pll pair<ll,ll> #define plll pair<ll,pll> //#define mp make_pair #define vv vector #define endl '\n' using namespace std; const int MAXN = 200*1000 + 5; const int MAXT = 263*1000; struct FenwickTree{ ll BITree[MAXN]; ll getSum(int index) { ll sum = 0; index = index + 1; while (index>0){ sum += BITree[index]; index -= index & (-index); } return sum; } void updateBIT(int index, ll val) { index = index + 1; while (index <= MAXN){ BITree[index] += val; index += index & (-index); } } void update(int a,int b,int c,int d,ll val){ updateBIT(d,val - get(a,b,c,d,d)); } ll get(int a,int b,int c,int l,int r){ ll cost = getSum(r); if(l != 0)cost -= getSum(l-1); return cost; } }; /* stage 1: still growing towards left. : sum of elements*time stage 2(a): end growing and stabilise: sum of elementrange. stage 2(b): grow and decay, hence no change: sum of element range stage 3: just decay: sum(elementrange) - sum(element size)*time stage 4: dead. We dont really need to keep track of this. // lets see how we can better the implementation. We have a period when there is a growth and then we have a period where there is a decay. Stage 2(a/b) can be calculated in terms of those. stage 4 is bleh, just kick it out. growth_end(i) = time when growth stops. decay_start(i) = time when decay starts. dead(i) = when we dont need to consider it. for every viable i, ans is Arr[i]*(min(growth_end(i),t) - max(0,t-decay_start(i))) => Arr[i]*(min(growth_end(i),t)) - Arr[i]*(max(0,t-decay_start(i))); */ int D = 0; int n; struct Event{ // =1 means growth_end(i) has been reached, and it wont grow anymore; // =2 means decay has been started. // type2 = ded. int type; int time; int item; Event(int a,int b,int c){ type = a; time = b; item = c; } }; int prev_greater[MAXN]; int next_greater[MAXN]; ll arr[MAXN]; void generateGreaters(int n){ stack<int> st1; stack<int> st2; FOR(i,n){ while(!st1.empty() and arr[st1.top()] < arr[i])st1.pop(); if(st1.empty())prev_greater[i] = -3*n; else prev_greater[i] = st1.top(); st1.push(i); while(!st2.empty() and arr[st2.top()] <= arr[n-i-1])st2.pop(); if(st2.empty())next_greater[n-i-1] = n; else next_greater[n-i-1] = st2.top(); st2.push(n-i-1); } } vv<Event> eventlist; void formEventList(int n){ FOR(i,n){ int delta1 = next_greater[i] - i; eventlist.pb(Event(1,delta1,i)); int delta2 = i - prev_greater[i]; delta2--; eventlist.pb(Event(2,delta2,i)); eventlist.pb(Event(3,delta2+delta1,i)); } sort(eventlist.begin(), eventlist.end(),[&](Event e1,Event e2){ if(e1.time == e2.time)return e1.type < e2.type; return e1.time < e2.time; }); } FenwickTree fenwick_expansion;// for expansion FenwickTree fenwick_stable;// when no expansion FenwickTree fenwick_decay;// when there is decay FenwickTree fenwick_decay_helper; // basically decay is like Arr[i]*(t-somevalue), and Arr[i]*somevalue is determined by this array. const int LOGN = 18; ll sparseTable[LOGN][MAXN]; void generateSparseTable(){ FOR(i,n)sparseTable[0][i] = prev_greater[i]; FORE(i,1,LOGN-1){ FOR(j,n){ int p = sparseTable[i-1][j]; if(p < 0 )sparseTable[i][j] = p; else sparseTable[i][j] = sparseTable[i-1][p]; } } } ll getAnsForPrefix(int x,int t){ ll cost = 0; int xcp = x; // here we are essentially finding the element presiding over the last element. for(int goUp = LOGN-1;goUp >= 0;goUp--){ if(sparseTable[goUp][x] >= 0 and xcp-sparseTable[goUp][x] <= t){ x = sparseTable[goUp][x]; } } cost += fenwick_expansion.get(0,0,n,0,x)*(t+1);// the expansion cost += fenwick_stable.get(0,0,n,0,x); cost -= fenwick_decay.get(0,0,n,0,x)*(t) - fenwick_decay_helper.get(0,0,n,0,x); cost -= (arr[x])*(min(max(0,t-(xcp-x)),(next_greater[x]-xcp-1))); return cost; } signed main(){ ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); int q; cin >> n >> q; FOR(i,n)cin >> arr[i]; iiii queries[q]; FOR(i,q){ int a,b,c; cin >> a >> b >> c; b--;c--; queries[i] = {{a,{b,c}},i}; } sort(queries,queries+q); generateGreaters(n); formEventList(n); generateSparseTable(); reverse(eventlist.begin(), eventlist.end()); // since we take elements from back FOR(i,n)fenwick_expansion.update(0,0,n,i,arr[i]); ll ans[q]; for(auto f : queries){ auto e = f.ff; int t = e.ff; int a = e.ss.ff;int b = e.ss.ss; // at time t, in range a to b; while(!eventlist.empty() and eventlist.back().time <= t){ // we have got more events to process yay !! Event e = eventlist.back();eventlist.pop_back(); int i = e.item; if(e.type == 1){ fenwick_expansion.update(0,0,n,i,0); fenwick_stable.update(0,0,n,i,arr[i]*e.time); }else if(e.type == 2){ fenwick_decay.update(0,0,n,i,arr[i]); fenwick_decay_helper.update(0,0,n,i,arr[i]*e.time); }else{ fenwick_stable.update(0,0,n,i,0); fenwick_decay_helper.update(0,0,n,i,0); fenwick_decay.update(0,0,n,i,0); } } ll cost = getAnsForPrefix(b,t); if(a != 0)cost -= getAnsForPrefix(a-1,t); ans[f.ss] = cost; } FOR(i,q){ cout << ans[i] << endl; } return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...