F. Moving Points
https://codeforces.com/contest/1311/problem/F
这是一道线段树类型的题;
可以用权值线段树或者树状数组来解;
所以,我们可以分为两部分,第一部分是计算出到当前点位置,小于等于当前点的速度的个数 ,总的个数乘当前点的速度
减去 小于等于当前点的速度的坐标总值即为答案;
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const int maxn=2e5+10; 5 int b[maxn]; 6 struct node 7 { 8 int x,v; 9 }a[maxn]; 10 bool cmp(node t1,node t2) 11 { 12 return t1.x<t2.x; 13 } 14 struct tre 15 { 16 int l;int r; 17 ll sum; 18 int num; 19 }tree[maxn<<2]; 20 void pushup(int root) 21 { 22 tree[root].sum=tree[root<<1].sum+tree[root<<1|1].sum; 23 tree[root].num=tree[root<<1].num+tree[root<<1|1].num; 24 } 25 void build(int l,int r,int root) 26 { 27 tree[root].l=l;tree[root].r=r; 28 tree[root].sum=0;tree[root].num=0; 29 if(l==r) return; 30 int mid=l+r>>1; 31 build(l,mid,root<<1); 32 build(mid+1,r,root<<1|1); 33 pushup(root); 34 } 35 void update(int pos,int val,int root) 36 { 37 int L=tree[root].l,R=tree[root].r; 38 if(L==R){ 39 tree[root].sum+=val; 40 tree[root].num+=1; 41 return; 42 } 43 int mid=L+R>>1; 44 if(pos<=mid) update(pos,val,root<<1); 45 else update(pos,val,root<<1|1); 46 pushup(root); 47 } 48 ll query(int pos,int flag,int root) 49 { 50 int L=tree[root].l; 51 int R=tree[root].r; 52 if(L==R){ 53 if(!flag) return tree[root].num; 54 else return tree[root].sum; 55 } 56 int mid=L+R>>1; 57 ll ans=0; 58 if(pos<=mid) ans+=query(pos,flag,root<<1); 59 else{ 60 if(!flag) ans+=tree[root<<1].num; 61 else ans+=tree[root<<1].sum; 62 ans+=query(pos,flag,root<<1|1); 63 } 64 return ans; 65 } 66 int main() 67 { 68 int n; 69 scanf("%d",&n); 70 for(int i=1;i<=n;i++){ 71 scanf("%d",&a[i].x); 72 } 73 for(int i=1;i<=n;i++){ 74 scanf("%d",&a[i].v); 75 b[i]=a[i].v; 76 } 77 sort(a+1,a+1+n,cmp); 78 sort(b+1,b+1+n); 79 int len=unique(b+1,b+1+n)-b-1; 80 ll ans=0; 81 build(1,2e5+10,1); 82 for(int i=1;i<=n;i++){ 83 int v=lower_bound(b+1,b+1+len,a[i].v)-b; 84 ans+=query(v,0,1)*a[i].x-query(v,1,1); 85 update(v,a[i].x,1); 86 } 87 printf("%lld\n",ans); 88 return 0; 89 90 }