제출 #1105656

#제출 시각아이디문제언어결과실행 시간메모리
1105656alexddFlooding Wall (BOI24_wall)C++17
56 / 100
129 ms25324 KiB
#include <bits/stdc++.h> #pragma GCC optimize("O3,unroll-loops") using namespace std; #define int long long const int MOD = 1e9+7; int n,cate; int a[500005],b[500005]; int prefmax[500005],suffmax[500005]; int p2[500005],inv2; int put(int x, int exp) { if(exp==0) return 1; if(exp%2==0) return put(x*x%MOD,exp/2); else return put(x*x%MOD,exp/2)*x%MOD; } map<int,int> mp,nrm; int inv[2000005]; int aint[8000005],lazy[8000005]; void build(int nod, int st, int dr) { lazy[nod]=1; if(st==dr) { aint[nod] = inv[dr]-inv[st-1]; return; } int mij=(st+dr)/2; build(nod*2,st,mij); build(nod*2+1,mij+1,dr); aint[nod] = (aint[nod*2] + aint[nod*2+1])%MOD; } void propagate(int nod) { if(lazy[nod]==1) return; lazy[nod*2] = (lazy[nod*2]*lazy[nod])%MOD; lazy[nod*2+1] = (lazy[nod*2+1]*lazy[nod])%MOD; aint[nod*2] = (aint[nod*2]*lazy[nod])%MOD; aint[nod*2+1] = (aint[nod*2+1]*lazy[nod])%MOD; lazy[nod]=1; } void upd(int nod, int st, int dr, int le, int ri, int newv) { assert(newv!=0); if(le>ri) return; if(le==st && dr==ri) { lazy[nod] = (lazy[nod]*newv)%MOD; aint[nod] = (aint[nod]*newv)%MOD; return; } propagate(nod); int mij=(st+dr)/2; upd(nod*2,st,mij,le,min(mij,ri),newv); upd(nod*2+1,mij+1,dr,max(mij+1,le),ri,newv); aint[nod] = aint[nod*2] + aint[nod*2+1]; } int qry(int nod, int st, int dr, int le, int ri) { if(le>ri) return 0; if(le==st && dr==ri) return aint[nod]; propagate(nod); int mij=(st+dr)/2; return qry(nod*2,st,mij,le,min(mij,ri)) + qry(nod*2+1,mij+1,dr,max(mij+1,le),ri); } int calc_0() { int rez=0; build(1,1,cate); for(int i=1;i<=n;i++) { int lim = prefmax[i-1]+1; if(lim >= b[i]+1) { rez = (rez + p2[n-i+1]*(qry(1,1,cate,nrm[lim],cate)%MOD))%MOD; } else { rez = (rez + p2[n-i]*(qry(1,1,cate,nrm[max(lim,a[i]+1)],cate)%MOD))%MOD; rez = (rez + p2[n-i]*(qry(1,1,cate,nrm[max(lim,b[i]+1)],cate)%MOD))%MOD; } upd(1,1,cate,nrm[b[i]+1],cate,2); } return rez; } int calc_1() { int rez=0; build(1,1,cate); for(int i=n;i>0;i--) { int lim = suffmax[i+1]+1; if(lim >= b[i]+1) { rez = (rez + qry(1,1,cate,nrm[lim],cate)%MOD*p2[i])%MOD; } else { rez = (rez + qry(1,1,cate,nrm[max(lim,a[i]+1)],cate)%MOD*p2[i-1])%MOD; rez = (rez + qry(1,1,cate,nrm[max(lim,b[i]+1)],cate)%MOD*p2[i-1])%MOD; } upd(1,1,cate,nrm[b[i]+1],cate,2); } return rez; } int calc_2() { int rez=0; build(1,1,cate); for(int i=1;i<=n;i++) upd(1,1,cate,nrm[b[i]+1],cate,2); for(int i=1;i<=n;i++) { upd(1,1,cate,nrm[b[i]+1],cate,inv2); int lim = max(prefmax[i-1], suffmax[i+1]) + 1; if(lim >= b[i]+1) { rez = (rez + 2LL*qry(1,1,cate,nrm[lim],cate))%MOD; } else { rez = (rez + qry(1,1,cate,nrm[max(lim,a[i]+1)],cate))%MOD; rez = (rez + qry(1,1,cate,nrm[max(lim,b[i]+1)],cate))%MOD; } upd(1,1,cate,nrm[b[i]+1],cate,2); } return rez; } int calc_3() { int rez=0; for(int i=1;i<=n;i++) { rez = (rez + 5LL*MOD + inv[cate] - (a[i]+1) + 1)%MOD; rez = (rez + 5LL*MOD + inv[cate] - (b[i]+1) + 1)%MOD; } for(int i=1;i<n;i++) rez = rez*2%MOD; return rez; } signed main() { ios_base::sync_with_stdio(0);cin.tie(0); p2[0]=1; for(int i=1;i<=500000;i++) p2[i] = p2[i-1]*2%MOD; inv2 = put(2,MOD-2); cin>>n; for(int i=1;i<=n;i++) cin>>a[i]; for(int i=1;i<=n;i++) { cin>>b[i]; if(a[i]>b[i]) swap(a[i],b[i]); mp[a[i]]++; mp[a[i]+1]++; mp[b[i]]++; mp[b[i]+1]++; } mp[0]++; mp[1]++; for(auto it:mp) { if(it.second==0) continue; nrm[it.first] = ++cate; inv[cate] = it.first; } int rez=0; for(int i=1;i<=n;i++) prefmax[i] = max(prefmax[i-1], a[i]); for(int i=n;i>0;i--) suffmax[i] = max(suffmax[i+1], a[i]); rez = (rez + calc_3() + calc_2())%MOD; rez = (rez + MOD - calc_0())%MOD; rez = (rez + MOD - calc_1())%MOD; cout<<rez; 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...
#Verdict Execution timeMemoryGrader output
Fetching results...