This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#pragma GCC optimize("Ofast")
#pragma GCC target("popcnt")
#include<bits/stdc++.h>
#include <chrono>
#include <random>
using namespace std;
#define F first
#define S second
#define pb push_back
#define vll vector<ll>
#define pll pair<ll, ll>
typedef long long ll;
const ll mod=1e9+7;
const ll mxN=5e5+5;
struct segtree{
vll tree, lazy;
ll treelen;
void init(ll siz){
treelen=siz+1;
while(__builtin_popcount(treelen)!=1){
treelen++;
}
tree=vll(2*treelen, 0);
lazy=vll(2*treelen, 1);
}
void push(ll idx, ll low, ll high){
if(low!=high){
lazy[2*idx]*=lazy[idx];
lazy[2*idx]%=mod;
lazy[2*idx+1]*=lazy[idx];
lazy[2*idx+1]%=mod;
}
}
void check(ll idx, ll low, ll high){
if(lazy[idx]==1) return;
tree[idx]*=lazy[idx];
tree[idx]%=mod;
push(idx, low, high);
lazy[idx]=1;
}
void update1(ll idx, ll low, ll high, ll qlow, ll qhigh, ll val){
//check(idx, low, high);
if(low>=qlow && high<=qhigh){
lazy[idx]*=val;
lazy[idx]%=mod;
check(idx, low, high);
return;
}
if(low>qhigh || high<qlow){
return;
}
ll mid=(low+high)/2;
check(2*idx, low, mid);
if(qlow<=mid) update1(2*idx, low, mid, qlow, qhigh, val);
check(2*idx+1, mid+1, high);
if(qhigh>=mid+1) update1(2*idx+1, mid+1, high, qlow, qhigh, val);
tree[idx]=tree[2*idx]+tree[2*idx+1];
}
ll getsum1(ll idx, ll low, ll high, ll qlow, ll qhigh){
check(idx, low, high);
if(low>=qlow && high<=qhigh){
return tree[idx];
}
if(low>qhigh || high<qlow){
return 0LL;
}
ll mid=(low+high)/2;
ll re=0;
if(qlow<=mid) re+=getsum1(2*idx, low, mid, qlow, qhigh);
if(qhigh>=mid+1) re+=getsum1(2*idx+1, mid+1, high, qlow, qhigh);
return re;
}
void setto1(ll idx, ll low, ll high, ll qlow, ll qhigh, ll val){
//check(idx, low, high);
if(low>=qlow && high<=qhigh){
tree[idx]=val;
tree[idx]%=mod;
//check(idx, low, high);
return;
}
if(low>qhigh || high<qlow){
return;
}
ll mid=(low+high)/2;
check(2*idx, low, mid);
if(qlow<=mid) setto1(2*idx, low, mid, qlow, qhigh, val);
check(2*idx+1, mid+1, high);
if(qhigh>=mid+1) setto1(2*idx+1, mid+1, high, qlow, qhigh, val);
tree[idx]=tree[2*idx]+tree[2*idx+1];
}
void update(ll qlow, ll qhigh, ll val){
update1(1, 0, treelen-1, qlow, qhigh, val);
}
ll getsum(ll qlow, ll qhigh){
return getsum1(1, 0, treelen-1, qlow, qhigh);
}
void setto(ll idx, ll val){
setto1(1, 0, treelen-1, idx, idx, val);
}
};
ll pw(ll a, ll b){
ll re=1;
a%=mod;
for(ll i=0;i<32;i++){
if(b&(1LL<<i)){
re*=a;
re%=mod;
}
a*=a;
a%=mod;
}
return re;
}
ll inv(ll a){
return pw(a, mod-2);
}
ll seg[mxN];
ll lef[mxN][2];
ll rig[mxN][2];
ll pw2[mxN];
bool good[mxN][2];
ll n;
ll a[mxN][2];
vector<pair<ll, pll>> v;
segtree SEG, SEG2, SEG3, SEG4;
ll inv2;
bool compare(pair<ll, pll> &a, pair<ll, pll> &b){
if(a.F!=b.F){
return a.F>b.F;
}
return a.S.F<b.S.F;
}
bool compare2(pair<ll, pll> &a, pair<ll, pll> &b){
if(a.F!=b.F){
return a.F>b.F;
}
return a.S.F>b.S.F;
}
void solve(){
memset(good, 0, sizeof(good));
cin>>n;
SEG.init(2*n+10);
SEG2.init(2*n+10);
SEG3.init(2*n+10);
for(ll i=0;i<n;i++){
cin>>a[i][0];
}
for(ll i=0;i<n;i++){
cin>>a[i][1];
}
for(ll i=0;i<n;i++){
v.pb({a[i][0], {i, 0}});
v.pb({a[i][1], {i, 1}});
seg[i]=2;
}
ll pre=2;
SEG3.setto(2*n, 1);
SEG3.setto(2*n+1, 1);
for(ll i=n-1;i>=0;i--){
SEG3.setto(2*i, pre);
SEG3.setto(2*i+1, pre);
pre*=2;
pre%=mod;
}
sort(v.begin(), v.end(), compare);
ll ans=0;
for(auto &it:v){
ll val=it.F;
ll id=it.S.F;
ll id2=it.S.S;
ll pre=1;
ll cur=0;
if(id>0){
cur=id*SEG2.getsum(0, 2*id-1);
cur%=mod;
if(cur<0) cur+=mod;
cur-=SEG.getsum(0, 2*id-1);
cur%=mod;
if(cur<0) cur+=mod;
cur*=inv(seg[id]);
cur%=mod;
}
ans+=cur*val;
ans%=mod;
ans+=(((val*((SEG3.getsum(0, 0)*inv(SEG3.getsum(2*id, 2*id)))%mod)))%mod)
*SEG3.getsum(2*(id+1), 2*(id+1));
ans%=mod;
ll tep=pw2[id]*SEG3.getsum(2*(id+1), 2*(id+1));
tep%=mod;
SEG2.setto(2*id+id2, tep);
SEG.setto(2*id+id2, (id*tep)%mod);
seg[id]--;
if(seg[id]==1){
SEG3.update(0, 2*id+1, inv2);
if(id>0){
SEG.update(0, 2*id-1, inv2);
SEG2.update(0, 2*id-1, inv2);
}
}
else{
SEG3.update(0, 2*id+1, 0);
if(id>0){
SEG.update(0, 2*id-1, 0);
SEG2.update(0, 2*id-1, 0);
}
}
}
//if(n>=10005) return;
SEG.init(2*n+10);
SEG2.init(2*n+10);
SEG3.init(2*n+10);
pre=2;
SEG3.setto(2*n, 1);
SEG3.setto(2*n+1, 1);
for(ll i=0;i<n;i++){
SEG3.setto(2*i, pre);
SEG3.setto(2*i+1, pre);
pre*=2;
pre%=mod;
}
sort(v.begin(), v.end(), compare2);
memset(good, 0, sizeof(good));
for(ll i=0;i<n;i++){
seg[i]=2;
}
for(auto &it:v){
ll val=it.F;
ll id=it.S.F;
ll id2=it.S.S;
ll pre=1;
ll cur=0;
if(id<n-1){
cur-=id*SEG2.getsum(2*(id+1), 2*n-1);
cur%=mod;
if(cur<0) cur+=mod;
cur+=SEG.getsum(2*(id+1), 2*n-1);
cur%=mod;
if(cur<0) cur+=mod;
cur*=inv(seg[id]);
cur%=mod;
}
ans+=cur*val;
ans%=mod;
ll tep;
if(id>0) tep=pw2[n-id-1]*SEG3.getsum(2*(id-1), 2*(id-1));
else tep=pw2[n-id-1];
tep%=mod;
SEG2.setto(2*id+id2, tep);
SEG.setto(2*id+id2, (id*tep)%mod);
seg[id]--;
if(seg[id]==1){
SEG3.update(2*id, 2*n-1, inv2);
if(id<n-1){
SEG.update(2*(id+1), 2*n-1, inv2);
SEG2.update(2*(id+1), 2*n-1, inv2);
}
}
else{
SEG3.update(2*id, 2*n-1, 0);
if(id<n-1){
SEG.update(2*(id+1), 2*n-1, 0);
SEG2.update(2*(id+1), 2*n-1, 0);
}
}
}
SEG.init(2*n+10);
SEG2.init(2*n+10);
SEG3.init(2*n+10);
SEG4.init(2*n+10);
pre=2;
SEG3.setto(2*n, 1);
SEG3.setto(2*n+1, 1);
for(ll i=0;i<n;i++){
SEG3.setto(2*i, pre);
SEG3.setto(2*i+1, pre);
pre*=2;
pre%=mod;
}
pre=2;
SEG4.setto(2*n, 1);
SEG4.setto(2*n+1, 1);
for(ll i=n-1;i>=0;i--){
SEG4.setto(2*i, pre);
SEG4.setto(2*i+1, pre);
pre*=2;
pre%=mod;
}
memset(good, 0, sizeof(good));
for(ll i=0;i<n;i++){
seg[i]=2;
}
ll preval=0;
vector<pair<ll, pll>> waiting;
//if(n>=10005) return;
for(auto &it:v){
ll val=it.F;
ll id=it.S.F;
ll id2=it.S.S;
ll pre=1;
ll cur=0;
if(val!=preval){
for(auto &it2:waiting){
ll val2=it2.F;
ll id23=it2.S.F;
ll id22=it2.S.S;
SEG2.setto(2*id23+id22, 0);
SEG.setto(2*id23+id22, 0);
if(seg[id23]==1){
SEG4.update(0, 2*id23+1, inv2);
}
else{
SEG4.update(0, 2*id23+1, 0);
}
}
waiting.clear();
}
if(id<n-1){
cur-=id*SEG2.getsum(2*(id+1), 2*n-1);
cur%=mod;
if(cur<0) cur+=mod;
cur+=SEG.getsum(2*(id+1), 2*n-1);
cur%=mod;
if(cur<0) cur+=mod;
cur*=inv(seg[id]);
cur%=mod;
}
ans-=cur*val;
ans%=mod;
if(ans<0) ans+=mod;
ll tep;
if(id>0) tep=SEG4.getsum(2*(id+1), 2*(id+1))*SEG3.getsum(2*(id-1), 2*(id-1));
else tep=SEG4.getsum(2*(id+1), 2*(id+1));
tep%=mod;
SEG2.setto(2*id+id2, tep);
SEG.setto(2*id+id2, (id*tep)%mod);
seg[id]--;
if(seg[id]==1){
SEG3.update(2*id, 2*n-1, inv2);
if(id<n-1){
SEG.update(2*(id+1), 2*n-1, inv2);
SEG2.update(2*(id+1), 2*n-1, inv2);
}
}
else{
SEG3.update(2*id, 2*n-1, 0);
if(id<n-1){
SEG.update(2*(id+1), 2*n-1, 0);
SEG2.update(2*(id+1), 2*n-1, 0);
}
}
preval=val;
waiting.pb(it);
}
//cout<<ans<<'\n';
for(ll i=0;i<n;i++){
for(ll j=0;j<2;j++){
ans-=a[i][j]*pw2[n-1];
ans%=mod;
if(ans<0) ans+=mod;
}
}
cout<<ans<<'\n';
}
int main(){
ios_base::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
inv2=inv(2);
pw2[0]=1;
for(ll i=1;i<mxN;i++){
pw2[i]=pw2[i-1]*2;
pw2[i]%=mod;
}
solve();
return 0;
}
Compilation message (stderr)
Main.cpp: In function 'void solve()':
Main.cpp:189:12: warning: unused variable 'pre' [-Wunused-variable]
189 | ll pre=1;
| ^~~
Main.cpp:248:12: warning: unused variable 'pre' [-Wunused-variable]
248 | ll pre=1;
| ^~~
Main.cpp:321:20: warning: unused variable 'val2' [-Wunused-variable]
321 | ll val2=it2.F;
| ^~~~
Main.cpp:317:12: warning: unused variable 'pre' [-Wunused-variable]
317 | ll pre=1;
| ^~~
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |