poj 1990 MooFest(树状数组)
来源:互联网 发布:怎样化妆 知乎 编辑:程序博客网 时间:2024/05/18 03:30
题目链接:http://poj.org/problem?id=1990
思路: 树状数组
分析:
1 题目给定n头牛的听力v[i]. 现在规定两头你i和j如果要进行交流的话那么消耗的能量就是dis(i,j)*max(v[i].v[j]),现在问n头牛总共的n*(n-1)*2种方式消耗的总的能量
2 题目要求的是所有的牛的交流方式的总的消耗能量
看这个样例
3 1
2 5
2 6
4 3
那么所有的区间为[1.3],[1,5],[1,6],[3,5],[3,6],[5,6]
那么总和为4*dis[1.3]+3*dis[1,5]+3*dis[1,6]+4*dis[3,5]+4*dis[3,6]+2*dis[5,6] = 4*(dis[1.3]+dis[3,5]+dis[3,6])+3*(dis[1,5]+dis[1,6])+2*(dis[5,6]);
那么题目要求的ans = ∑(v[i]*(所有比v[i]小的牛的坐标的总和))
3 那么我们来分解这个式子,我们对点按照音量的值从小到大排完序之后
那么对于任一的一点i,i之前的牛的音量值肯定小于v[i],但是坐标的值可能比x[i]大也可能比x[i]小,因此我们应该分成两部分来考虑,就是坐标是i的左边和右边
首先考虑左边的情况,假设左边比小于等于v[i]的牛有三头坐标分别为a b c,那么左边的值就是v[i]*(x[i]-a)+v[i]*(x[i]-b)+v[i]*(x[i]-c) => v[i]*(3*x[i]-(a+b+c))
那么我们假设左边小于v[i]的牛有countLeft头,总的坐标为totalLeft,那么左边的值为v[i]*(countLeft*x[i]-totalLeft);
接下来考虑右边的情况,由于我们已经按照v的值排序,那么我们能够很好的计算出小于等于v[i]的音量值的总的坐标之后,我们设为totalDis,那么根据左边求出的小于
等于v[i]的个数为countLeft,那么右边的个数为i-countLeft,那么同理右边的坐标之和为totalDis-totalLeft , 那么右边的值为v[i]*(totalDis-totalLeft-(i-countLeft)*x[i]);
那么对于排序后的第i头牛来说比它小的音量的牛的值为v[i]*(countLeft*x[i]-totalLeft)+v[i]*(totalDis-totalLeft-(i-countLeft)*x[i]);
4 我们已经知道了公式,现在我们只要去求countLeft和totalLeft即可,由于我们已经按照v的值排序, 那么我们只要对坐标建立两个树状数组即可。一个用来存储个数,一个用来存储坐标之和,那么对于第i头牛来说我们就能够在O(logn)的时间内求出countLeft和totalLeft
#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>using namespace std;const int MAXN = 100010;struct Node{ int x,v; bool operator <(const Node& tmp)const {return v<tmp.v; }}node[MAXN];int n ;int treedis[MAXN];int treeNum[MAXN];int lowbit(int x){ return x&(-x);}long long getSum_dis(int x){ long long sum = 0; while(x){ sum += treedis[x]; x -= lowbit(x); } return sum;}long long getSum_num(int x){ long long sum = 0; while(x){ sum += treeNum[x]; x -= lowbit(x); } return sum;}void add_num(int x , int val){ while(x < MAXN){ treeNum[x] += val; x += lowbit(x); }}void add_dis(int x , int val){ while(x < MAXN){ treedis[x] += val; x += lowbit(x); }}void solve(){memset(treedis,0,sizeof treedis);memset(treeNum,0,sizeof treeNum);sort(node,node+n);long long totaldis=0,ans=0;for(int i=0;i<n;i++){long long totalleft=getSum_dis(node[i].x);long long countleft=getSum_num(node[i].x);ans+=node[i].v*(countleft*node[i].x-totalleft);ans+=node[i].v*(totaldis-totalleft-(i-countleft)*node[i].x);totaldis+=node[i].x;add_dis(node[i].x,node[i].x);add_num(node[i].x,1);}printf("%lld\n",ans);}int main(){ while(~scanf("%d" , &n)) { for(int i = 0 ; i < n ; i++){scanf("%d%d",&node[i].v,&node[i].x);}solve(); } return 0;}
- poj 1990 MooFest (两个树状数组)
- POJ 1990 MooFest(树状数组)
- POJ 1990-MooFest(树状数组)
- MooFest(POJ-1990)(树状数组)
- POJ 1990 MooFest(二维树状数组)
- POJ 1990 MooFest(树状数组)
- poj 1990 MooFest(树状数组)
- POJ 1990 MooFest(树状数组)
- [POJ 1990] MooFest (树状数组)
- POJ 1990 MooFest(树状数组)
- poj 1990 MooFest (树状数组)
- poj 1990 MooFest(树状数组)
- poj 1990 MooFest(树状数组变形)
- POJ 1990 MooFest (树状数组)
- poj 1990 MooFest(树状数组)
- poj 1990 MooFest (树状数组)
- poj 1990 MooFest(树状数组)
- 【poj 1990】MooFest(树状数组)
- 【备忘】传智播客最新大数据第3期实战培训完整版视频教程
- delphi chrome cef3 控件学习笔记 (四)
- C语言free报错
- myBatis使用collection
- 物联网平台机智云Android开源框架入门之旅(三)分析设备详情界面的中如何发送各种指令到云端。
- poj 1990 MooFest(树状数组)
- Spring MVC中只返回数据不跳转页面
- 套接字和在标准I|O之间的转化
- 剔除集合中的不符合条件项,使用迭代器和remove函数。
- GCD 简述、使用等详解
- Hibernate ilike中转义字符的处理
- PHP URL重定向的三种方法
- iphone的尺寸以及对应开发时的宽高
- Hibernate中C3P0配置