51nod 1394 差和问题(算法马拉松8)
来源:互联网 发布:linux将目录打包 编辑:程序博客网 时间:2024/05/16 19:02
有一个集合S,初始状态下有n个元素,对他进行如下操作:
1、向S里面添加一个值为v的元素。输入格式为1 v
2、向S里面删除一个值为v的元素。输入格式为2 v
3、询问S里面的元素两两之差绝对值之和。输入格式为3
对于样例,
操作3,|1-2|+|1-3|+|2-3|=4
操作1 4之后,集合中的数字为1 2 3 4
操作3,|1-2|+|1-3|+|2-3|+|1-4|+|2-4|+|3-4|=10
操作2 2之后,集合中的数字为1 3 4
操作3,|1-3|+|1-4|+|3-4|=6
Input
第一行输入两个整数n,Q表示集合中初始元素个数和操作次数。(1<=n,Q<=100,000)第二行给出n个整数a[0],a[1],a[2],…,a[n-1],表示初始集合中的元素。(0<=a[i]<=1,000,000,000) 接下来Q行,每行一个操作。(0<=v<=1,000,000,000)
Output
对于第2类操作,如果集合中不存在值为v的元素可供删除,输出-1。对于第3类操作,输出答案。
Input示例
3 51 2 331 432 23
Output示例
4106
解题思路
离散化+树状数组,对每次1,2操作,用树状数组要统计比它大的个数和比它小的个数
代码:
#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int maxn=200000+100;struct node{ int id; long long v;}q[maxn];long long a[maxn*4];int b[maxn*4];long long t[maxn];long long cur[maxn];int cou[maxn];long long low(int k){ return k&(-k);}void update(int k,long long v,int v2){ while(k<maxn) { a[k]+=v; b[k]+=v2; k+=low(k); }}long long anss,ansn;long long sums(int k){ anss=0,ansn=0; while(k>0) { anss+=a[k]; ansn+=b[k]; k-=low(k); }}int main(){ int n,qu; while(~scanf("%d%d",&n,&qu)) { for(int i=0; i<n; i++) { scanf("%I64d",&t[i]); cur[i]=t[i]; } int cnt=n; for(int i=0; i<qu; i++) { scanf("%d",&q[i].id); if(q[i].id!=3) { scanf("%I64d",&q[i].v); cur[cnt]=q[i].v; cnt++; } } sort(cur,cur+cnt); int all=unique(cur,cur+cnt)-cur; long long sum=0,ans=0; int sumn=0; int temp; for(int i=0;i<n;i++) { temp=lower_bound(cur,cur+all,t[i])-cur+1; cou[temp]++; sumn++; update(temp,t[i],1); sum+=t[i]; sums(temp); ans=ans+(t[i]*(ansn*2-sumn)-2*anss+sum); // cout<<ans<<endl; } long long cwt; for(int i=0;i<qu;i++) { if(q[i].id==1) { //cout<<q[i].id<<" "<<q[i].v<<endl; temp=lower_bound(cur,cur+all,q[i].v)-cur+1; // cout<<temp<<endl; update(temp,q[i].v,1); cou[temp]++; sum+=q[i].v; sumn++; sums(temp); // cout<<q[i].v*(ansn*2-sumn)-2*anss+sum<<endl; // cout<<anss<<" "<<ansn<<" "<<sum<<" "<<q[i].v<<endl; ans=ans+(q[i].v*(ansn*2-sumn)-2*anss+sum); // cout<<ans<<endl; } else if(q[i].id==2) { temp=lower_bound(cur,cur+all,q[i].v)-cur+1; if(cou[temp]==0) { printf("-1\n"); } else { sums(temp); ans=ans-(q[i].v*(ansn*2-sumn)-2*anss+sum); update(temp,-q[i].v,-1); cou[temp]--; sum-=q[i].v; sumn--; } } else if(q[i].id==3) { printf("%I64d\n",ans); } } } return 0;}
0 0
- 51nod 1394 差和问题(算法马拉松8)
- 算法马拉松8(差和问题)
- 51nod 1824(算法马拉松30)
- 51nod 1394:差和问题
- 51nod 1394 差和问题
- 51Nod-1394-差和问题
- 51nod 算法马拉松12
- 51nod算法马拉松20
- 51Nod 算法马拉松23
- 51Nod 算法马拉松24
- 51nod算法马拉松25
- 51NOD算法马拉松 最大值问题 离线预处理+set lower_bound
- 矩阵模板 51nod 算法马拉松分解问题
- 【51Nod算法马拉松18 A】染色问题
- 【51nod】【算法马拉松14】1586 约数和
- 51nod 算法马拉松6(索函数)(规律题目)
- 51nod算法马拉松23(飞越愚人节)
- 51nod-1394 差和问题(树状数组)
- 请把我风干成你的回忆
- 基于JDK API实现文件的压缩与解压
- Chrome下最简分页打印方案
- SpringMVC下打包文件的下载
- 多线程之生产者消费者模型
- 51nod 1394 差和问题(算法马拉松8)
- Jquery Validation实用示例及讲解
- Hibernate Validation使用示例及讲解
- 前后台校验示例及讲解
- Cookie的使用讲解及示例
- Mybatis实用Mapper SQL汇总示例
- C++primer plus第六版课后编程练习答案10.5
- windows server 2003 DHCP服务迁移到server2008
- 十二、编写高质量的代码——思想为源(笔记)