제출 #1219309

#제출 시각아이디문제언어결과실행 시간메모리
1219309Plot_TwistFancy Fence (CEOI20_fancyfence)C++20
100 / 100
38 ms33336 KiB
// Using Cartesian Tree #include<bits/stdc++.h> #include<chrono> #include <ext/pb_ds/assoc_container.hpp> #include <ext/pb_ds/tree_policy.hpp> using namespace __gnu_pbds; using namespace std; using namespace chrono; #define ll long long #define vl vector<long long> #define endl '\n' const int MOD = 1e9 + 7; void inputv(vl &v) {for(int i = 0; i < v.size(); i++) cin>>v[i];} void printv(vl v) {for(auto i : v) cout<<i<<" ";cout<<endl;} // #ifndef ONLINE_JUDGE // #include "template.cpp" // #else // #define debug(...) // #define debugArr(...) // #endif #define int long long typedef tree< int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> ordered_set; /* for min SparseTable sp(arr, [&](const int& a, const int& b) { return min(a,b); }); */ template<class T, class Fun = function<T(const T &, const T &)>> struct SparseTable { vector<vector<T>> sp; Fun f; SparseTable(vector<T> &a, const Fun &g) : f(g) { int n = a.size(); int lg = __lg(n) + 1; sp.resize(lg, vector<T>(n)); for(int i = 0; i < n; i++) sp[0][i] = a[i]; for(int j = 0; j < (lg-1); j++) { for(int i = 0; i < n; i++) { if (i + (1 << (j + 1)) > n) break; sp[j + 1][i] = f(sp[j][i], sp[j][i + (1 << j)]); } } } T get(int l, int r) { int k = __lg(r - l); return f(sp[k][l], sp[k][r - (1 << k)]); } }; typedef struct Node { int h; int w; int l; int r; Node* left; Node* right; }Node; signed main() { // #ifndef ONLINE_JUDGE // freopen("input.txt","r",stdin); // freopen("output.txt","w",stdout); // freopen("Error.txt","w",stderr); // #endif ios::sync_with_stdio(false); cin.tie(NULL); // #ifndef ONLINE_JUDGE // auto start = duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count(); // #endif int n; cin>>n; vl ht(n), wt(n); inputv(ht);inputv(wt); vl ord(n); iota(ord.begin(), ord.end(), 0); SparseTable st(ord, [&](const int& i, const int& j) { return make_pair(ht[i], i) < make_pair(ht[j], j) ? i:j; }); function<Node*(int l, int r)> build = [&](int l, int r)->Node* { if(l>r) return nullptr; int temp = st.get(l,r+1); Node *root = new Node(); root->h = ht[temp]; root->w = wt[temp]; root->left = build(l,temp-1); root->right = build(temp+1,r); root->l = 0; root->r = 0; if(root->left) root->l = (((root->left)->l +(root->left)->r)%MOD+ (root->left)->w)%MOD; if(root->right) root->r = (((root->right)->l +(root->right)->r)%MOD+ (root->right)->w)%MOD; return root; }; Node *root = build(0,n-1); int ans = 0; function<void(Node*)> solve = [&](Node* curr) { if(!curr) return; int temp = (curr->l * ((curr->w + curr->r)%MOD))%MOD; temp = (temp + (curr->r * curr->w)%MOD)%MOD; temp = (temp + ((curr->w*(curr->w + 1))/2)%MOD)%MOD; int temp2 = ((curr->h * (curr->h + 1))/2)%MOD; ans = (ans + (temp*temp2)%MOD)%MOD; solve(curr->left); solve(curr->right); }; solve(root); cout<<ans<<endl; // #ifndef ONLINE_JUDGE // auto stop = duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count(); // cerr << "Took " << stop - start << "ms" << endl; // #endif }
#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...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...