Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include<bits/stdc++.h>
- #include <ext/pb_ds/assoc_container.hpp>
- using namespace __gnu_pbds;
- using namespace std;
- #define int long long
- #define ps(x,y) fixed<<setprecision(y)<<x
- #define ld long double
- #define fastio ios_base::sync_with_stdio(false); cin.tie(NULL);
- #define endl "\n"
- #define setbits(x) __builtin_popcount(x)
- #define gcd(a,b) __gcd(a,b)
- #define minv(v) *min_element(v.begin(), v.end())
- #define maxv(v) *max_element(v.begin(), v.end())
- #define print(v) for(auto k : v) cout<<k<<" "; cout<<endl;
- const int mod = 1e9+7;
- const int bit = 31;
- #define input(a) for(int i=0; i<a.size(); i++) cin>>a[i];
- typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> pbds;
- //__________________________________________________________________________________________________________________
- struct node{
- int singlet = 0;
- int doublet = 0;
- int triplet = 0;
- };
- int arr[100005];
- node seg[4*100005];
- void build(int idx, int lo, int hi)
- {
- if(lo == hi)
- {
- seg[idx].singlet = arr[lo];
- return;
- }
- int mid = (lo + hi)/2;
- build(2*idx + 1, lo, mid);
- build(2*idx + 2, mid+1, hi);
- seg[idx].singlet = (seg[2*idx + 1].singlet + seg[2*idx+2].singlet)%mod;
- seg[idx].doublet = ((seg[2*idx + 1].doublet + seg[2*idx+2].doublet)%mod + (seg[2*idx+1].singlet*seg[2*idx+2].singlet)%mod)%mod;
- seg[idx].triplet = ((seg[2*idx+1].triplet + seg[2*idx+2].triplet)%mod + (seg[2*idx+1].doublet*seg[2*idx+2].singlet)%mod + (seg[2*idx+2].doublet*seg[2*idx+1].singlet)%mod)%mod;
- }
- node query(int idx, int lo, int hi, int l, int r)
- {
- //complete overlap
- if(lo >= l && hi <= r)
- return seg[idx];
- //no overlap
- if(hi < l || lo > r)
- {
- node ans;
- return ans;
- }
- int mid = (lo + hi)/2;
- node left = query(2*idx+1, lo, mid, l, r);
- node right = query(2*idx+2, mid+1, hi, l, r);
- node ans;
- ans.singlet = (left.singlet + right.singlet)%mod;
- ans.doublet = ((left.doublet + right.doublet)%mod + (left.singlet*right.singlet)%mod)%mod;
- ans.triplet = ((left.triplet + right.triplet)%mod + (left.doublet*right.singlet)%mod + (right.doublet*left.singlet)%mod)%mod;
- return ans;
- }
- int32_t main()
- {
- fastio;
- int n;
- cin>>n;
- for(int i=0; i<n; i++)
- cin>>arr[i];
- build(0, 0, n-1);
- int q;
- cin>>q;
- while(q--)
- {
- int l,r;
- cin>>l>>r;
- node ans = query(0, 0, n-1, l, r);
- cout<<ans.triplet<<endl;
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement