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,unroll-loops")
#pragma GCC target("popcnt,avx,avx2")
#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{
ll tree[8*mxN];
ll lazy[8*mxN];
ll treelen;
void init(ll siz){
treelen=siz+1;
while(__builtin_popcount(treelen)!=1){
treelen++;
}
memset(tree, 0, sizeof(tree));
for(ll i=0;i<2*treelen;i++) lazy[i]=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);
}
struct BIT{
ll tree[2*mxN];
ll siz;
void init(ll sz){
siz=sz+1;
for(ll i=1;i<siz;i++){
tree[i]=1;
}
}
void update(ll idx, ll val){
idx++;
for(;idx<siz;idx+=(idx&-idx)){
tree[idx]*=val;
tree[idx]%=mod;
}
}
ll getpre(ll idx){
idx++;
ll re=1;
for(;idx>0;idx-=(idx&-idx)){
re*=tree[idx];
re%=mod;
}
return re;
}
ll getrng(ll a, ll b){
if(a==0) return getpre(b);
return (getpre(b)*inv(getpre(a-1)))%mod;
}
};
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;
BIT SEG3, SEG4;
ll inv2;
ll val, id, id2, pre, cur, val2, id23, id22;
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(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.update(n, 1);
for(ll i=n-1;i>=0;i--){
SEG3.update(i, 2);
}
sort(v.begin(), v.end(), compare);
ll ans=0;
for(auto &it:v){
val=it.F;
id=it.S.F;
id2=it.S.S;
pre=1;
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;
if(seg[id]==2){
cur*=inv2;
cur%=mod;
}
}
ans+=cur*val;
ans%=mod;
ans+=((val*(SEG3.getrng(0, n-1))%mod)*inv(seg[id]));
ans%=mod;
ll tep=pw2[id]*SEG3.getrng(0, n-id-2);
tep%=mod;
SEG2.setto(2*id+id2, tep);
SEG.setto(2*id+id2, (id*tep)%mod);
seg[id]--;
if(seg[id]==1){
SEG3.update(n-1-id, inv2);
if(id>0){
SEG.update(0, 2*id-1, inv2);
SEG2.update(0, 2*id-1, inv2);
}
}
else{
SEG3.update(n-1-id, 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(n+10);
pre=2;
SEG3.update(n, 1);
for(ll i=0;i<n;i++){
SEG3.update(i, 2);
}
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){
val=it.F;
id=it.S.F;
id2=it.S.S;
pre=1;
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;
if(seg[id]==2){
cur*=inv2;
cur%=mod;
}
}
ans+=cur*val;
ans%=mod;
ll tep;
if(id>0) tep=pw2[n-id-1]*SEG3.getrng(0, 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(id, 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(id, 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(n+10);
SEG4.init(n+10);
pre=2;
SEG3.update(n, 1);
for(ll i=0;i<n;i++){
SEG3.update(i, 2);
}
pre=2;
SEG4.update(n, 1);
for(ll i=n-1;i>=0;i--){
SEG4.update(i, 2);
}
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>=mxN-10) return;
ll pt=0;
pair<ll, pll> it2;
for(auto &it:v){
val=it.F;
id=it.S.F;
id2=it.S.S;
pre=1;
cur=0;
if(val!=preval){
for(;pt<waiting.size();pt++){
it2=waiting[pt];
val2=it2.F;
id23=it2.S.F;
id22=it2.S.S;
SEG2.setto(2*id23+id22, 0);
SEG.setto(2*id23+id22, 0);
if(seg[id23]==1){
SEG4.update(n-1-id23, inv2);
}
else{
SEG4.update(n-1-id23, 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;
if(seg[id]==2){
cur*=inv2;
cur%=mod;
}
}
ans-=cur*val;
ans%=mod;
if(ans<0) ans+=mod;
ll tep;
if(id>0) tep=SEG4.getrng(0, n-id-2)*SEG3.getrng(0, id-1);
else tep=SEG4.getrng(0, n-id-2);
tep%=mod;
SEG2.setto(2*id+id2, tep);
SEG.setto(2*id+id2, (id*tep)%mod);
seg[id]--;
if(seg[id]==1){
SEG3.update(id, 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(id, 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:349:20: warning: comparison of integer expressions of different signedness: 'll' {aka 'long long int'} and 'std::vector<std::pair<long long int, std::pair<long long int, long long int> > >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
349 | for(;pt<waiting.size();pt++){
| ~~^~~~~~~~~~~~~~~
Main.cpp:214:8: warning: variable 'pre' set but not used [-Wunused-but-set-variable]
214 | ll pre=2;
| ^~~
# | 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... |