Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <bits/stdc++.h>
- using namespace std;
- const int MXV = 1000004;
- struct NODE{
- int subsets , ans , lazy;
- NODE(){
- subsets = ans = 0;
- lazy = 1;
- }
- NODE(int sub , int an){
- subsets = sub;
- ans = an;
- lazy = 1;
- }
- }tree[MXV * 4];
- const int MX = (1<<18) , MOD = 1000000007;
- vector < int > used;
- int T , n;
- pair < int , int > arr[MX];
- int where , toadd;
- int st , en , maxVal = 1000000;
- void mul(int x , int coef){
- tree[x].ans = (1ll * tree[x].ans * coef)%MOD;
- tree[x].subsets = (1ll * tree[x].subsets * coef)%MOD;
- tree[x].lazy = (1ll * tree[x].lazy * coef)%MOD;
- }
- void push(int x){
- if(tree[x].lazy== 1) return;
- mul(x*2 , tree[x].lazy);
- mul(x*2+1 , tree[x].lazy);
- tree[x].lazy = 1;
- }
- void update(int x , int a , int b){
- used.push_back(x);
- if(st > b || en < a) return;
- if(a >= st && b <= en){
- mul(x , 2);
- return;
- }
- push(x);
- update(x*2 , a , (a+b)/2);
- update(x*2+1 , (a+b)/2+1 , b);
- tree[x].ans = tree[x*2].ans + tree[x*2+1].ans; tree[x].ans %= MOD;
- tree[x].subsets = tree[x*2].subsets + tree[x*2+1].subsets; tree[x].subsets %= MOD;
- }
- NODE query(int x , int a , int b){
- if(st > b || en < a) return NODE();
- if(a >= st && b <= en) return tree[x];
- push(x);
- auto L = query(x*2 , a , (a+b)/2) , R = query(x*2+1 , (a+b)/2+1 , b);
- return NODE((L.subsets + R.subsets)%MOD , (L.ans + R.ans)%MOD);
- }
- void add(int x , int a , int b){
- if(where > b || where < a) return;
- used.push_back(x);
- if(a == b){
- tree[x].subsets += toadd; tree[x].subsets %= MOD;
- tree[x].ans = (1ll * tree[x].subsets * a)%MOD;
- return;
- }
- push(x);
- if(where <= (a+b)/2) add(x*2 , a , (a+b)/2);
- else add(x*2+1 , (a+b)/2+1 , b);
- tree[x].ans = tree[x*2].ans + tree[x*2+1].ans; tree[x].ans %= MOD;
- tree[x].subsets = tree[x*2].subsets + tree[x*2+1].subsets; tree[x].subsets %= MOD;
- }
- int main(int argc, char** argv){
- //freopen("in.in","r",stdin);
- scanf("%d",&T);
- while(T--){
- scanf("%d",&n);
- for(int j = 1 ; j <= n ; j++) scanf("%d",&arr[j].first);
- for(int j = 1 ; j <= n ; j++) scanf("%d",&arr[j].second);
- sort(arr+1 , arr+1+n);
- long long tot = 0;
- for(int j = 1 ; j <= n ; j++){
- int V = arr[j].second;
- st = V + 1 , en = maxVal;
- if(st <= en) tot += (1ll * arr[j].first * query(1,1,maxVal).ans); tot %= MOD;
- if(st <= en) update(1,1,maxVal);
- st = 1 , en = V;
- if(st <= en) toadd = query(1,1,maxVal).subsets;
- ++toadd; toadd%=MOD;
- tot += (1ll * ((1ll * arr[j].first * arr[j].second)%MOD) * toadd)%MOD; tot %= MOD;
- where = V;
- add(1,1,maxVal);
- }
- cout<<tot<<endl;
- for(auto pp : used)
- tree[pp] = NODE();
- used.clear();
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement