1394 差和问题

1394 差和问题

基准时间限制:1 秒 空间限制:131072 KB

有一个多重集合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 5
1 2 3
3
1 4
3
2 2
3

Output示例

4
10
6思路:离散化+数状数组;维护两个树状数组,一个为区间的和,另一个为区间个数,然后离线查询。插入和删除一个数字的时候要统计一下这个对答案的影响。当前数字为x,比当前数字小的有cnt个,总和为sum,那么这一部分对答案的影响是x*cnt-sum.对于求比当前数字大的数字类似的道理。
  1 #include<stdio.h>
  2 #include<algorithm>
  3 #include<iostream>
  4 #include<stdlib.h>
  5 #include<queue>
  6 #include<string.h>
  7 #include<math.h>
  8 #include<map>
  9 using namespace std;
 10 typedef long long LL;
 11 LL num[100005];
 12 typedef struct node
 13 {
 14         LL x;
 15         int op;
 16         int  id;
 17 } ss;
 18 typedef struct pp
 19 {
 20         LL x;
 21         LL id;
 22 } ap;
 23 ss ask[100005];
 24 map<LL,int>my;
 25 LL ac[400000];
 26 int id[100005];
 27 LL bit_ans[200005];
 28 LL bit_sum[200005];
 29 LL sum1(int i);
 30 void add1(int i,LL x,int n);
 31 LL sum2(int i);
 32 void add2(int i,LL x,int n);
 33 LL akk[100005];
 34 int main(void)
 35 {
 36         int n,Q;
 37         scanf("%d %d",&n,&Q);
 38         int i,j;
 39         my.clear();
 40         int cn = 0;
 41         memset(bit_ans,0,sizeof(bit_ans));
 42         memset(bit_sum,0,sizeof(bit_sum));
 43         for(i = 0; i < n; i++)
 44         {
 45                 scanf("%lld",&num[i]);
 46                 ac[cn++] = num[i];
 47         }
 48         for(i = 1; i <= Q; i++)
 49         {
 50                 int x,y;
 51                 scanf("%d",&ask[i].op);
 52                 if(ask[i].op != 3)
 53                 {
 54                         scanf("%lld",&ask[i].x);
 55                         ac[cn++] = ask[i].x;
 56                 }
 57                 ask[i].id = i;
 58         }//printf("1\n");
 59         sort(num,num+n);
 60         sort(ac,ac+cn);
 61         int acc = 1;
 62         LL x = ac[0];
 63         my[x] = 1;
 64         for(i = 1; i < cn; i++)
 65         {
 66                 if(x!=ac[i])
 67                 {
 68                         acc++;
 69                         x= ac[i];
 70                         my[x] = acc;
 71                 }
 72         }
 73         LL summ = 0;
 74         for(i = 0; i < n; i ++)
 75         {
 76                 int uv = my[num[i]];
 77                 summ += sum2(uv-1)*num[i] - sum1(uv-1);
 78                 add1(uv,num[i],acc);
 79                 add2(uv,1,acc);
 80         }
 81         akk[0]=summ;
 82         for(i = 1; i <= Q; i++)
 83         {
 84                 if(ask[i].op==2)
 85                 {
 86                         int ic = my[ask[i].x];
 87                         LL a = sum2(ic)-sum2(ic-1);
 88                         if(!a){printf("-1\n");akk[i] = akk[i-1];}
 89                         else
 90                         {
 91                                 LL smal_x1 = sum2(ic-1);
 92                                 LL smal_y1 = sum1(ic-1);
 93                                 LL maxx_x1 = sum2(acc)-sum2(ic);
 94                                 LL maxx_y1 = sum1(acc)-sum1(ic);
 95                                 akk[i] = akk[i-1] - (smal_x1)*ask[i].x + smal_y1 - maxx_y1 + maxx_x1*ask[i].x;
 96                                 add1(ic,-ask[i].x,cn);
 97                                 add2(ic,-1,cn);
 98                         }
 99                 }
100                 else if(ask[i].op == 1)
101                 {
102                         int ic = my[ask[i].x];
103                         LL smal_x1 = sum2(ic-1);
104                         LL smal_y1 = sum1(ic-1);
105                         LL maxx_x1 = sum2(acc)-sum2(ic);
106                         LL maxx_y1 = sum1(acc)-sum1(ic);
107                         akk[i] = akk[i-1] + (smal_x1)*ask[i].x - smal_y1 + maxx_y1 - maxx_x1*ask[i].x;
108                         add1(ic,ask[i].x,cn);
109                         add2(ic,1,cn);
110                 }
111                 else
112                 {
113                         akk[i] = akk[i-1];
114                         printf("%lld\n",akk[i]);
115                 }
116         }
117         return 0;
118 }
119 LL sum1(int i)
120 {
121         LL s = 0;
122         while(i>0)
123         {
124                 s+=bit_sum[i];
125                 i -= i & -i;
126         }
127         return s;
128 }
129 void add1(int i,LL x,int n)
130 {
131         while(i <= n)
132         {
133                 bit_sum[i] += x;
134                 i += i&(-i);
135         }
136 }
137 LL sum2(int i)
138 {
139         LL s = 0;
140         while(i>0)
141         {
142                 s+=bit_ans[i];
143                 i -= i & -i;
144         }
145         return s;
146 }
147 void add2(int i,LL x,int n)
148 {
149         while(i <= n)
150         {
151                 bit_ans[i] += x;
152                 i += i&(-i);
153         }
154 }
时间: 2024-10-03 22:03:44

1394 差和问题的相关文章

51 nod 1394 1394 差和问题(线段树)

1394 差和问题基准时间限制:1 秒 空间限制:131072 KB 分值: 80 难度:5级算法题 有一个多重集合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-

51nod1394 差和问题

我只会用线段树写...不喜欢树状数组..其实跑的也不算慢?然后各种*的时候忘了longlong一直WA...药丸! 而且我不怎么会用map离散化...那么就sort+unique #include<cstdio> #include<cstring> #include<cctype> #include<algorithm> using namespace std; #define rep(i,s,t) for(int i=s;i<=t;i++) #def

最大边和最小边之差最小的生成树 UVA 1394

题目大意:给你n个点的图,求苗条度(最大边减最小编)尽量小的生成树 思路:sort以后暴力枚举区间即可 //看看会不会爆int!数组会不会少了一维! //取物问题一定要小心先手胜利的条件 #include <bits/stdc++.h> using namespace std; #define LL long long #define ALL(a) a.begin(), a.end() #define pb push_back #define mk make_pair #define fi f

在“春晚”夹击中实现差异化突围 一直播春节系列活动吸睛

自1983年举办至今,央视春节联欢晚会已经成为了中国规模最大.最受关注.收视率最高.影响力最大的综艺晚会.就在2017鸡年央视春晚上,截止当晚22时30分网络收看人数达1.04亿,手机和移动端占比超七成.鸡年春晚除了延续品牌神话外,也给在移动端上和春晚同台竞技的直播平台们带来了巨大的挑战. 截止除夕夜12时,一直播独家策划的"直播过大年"春节直播活动累计观看次数突破6600万,最高同时在线峰值突破450万:同时,持续数十天的一直播"星拜年"活动,已有超过150位明星

《巨婴国》:差评。伪科学/非科学,逻辑比较差,以偏概全,解释牵强,竖起一个稻草人打得挺嗨。1星

读后感觉比较差.只能给1星.相当于负分的水平. 作者认为中国人大部分是没长大的婴儿,不能正确处理人际关系,隐含地推论常见的心理疾病.变态人格.不正常情商都是巨婴病的表现,明确地推论巨婴理论可以解释许多世界历史和国际政治上的事情. 差评理由有下面几个: 1:“巨婴国”的学说到底是不是一个严肃的学术上的推论?我认为不是.我认为可以归入伪科学或非科学的范畴.作者虽然是北大心理学系的本科和硕士毕业,但是全书是浓郁的江湖派的风格.作者提到了一个惊世骇俗的“巨婴学说”,并且断定中国人大部分是“巨婴”,因此中

还在吐槽翻译的外版书质量差吗?谈谈我个人的理解

很难想象哪个学习计算机技术的人是没看过这方面书籍的,如果只是在网上看看技术贴,那样得来的知识绝对是离散的,不系统的.而要真正学好一门学问(比如一门计算机语言或者一门技术),一本好书的作用是不言而喻的.很多人抱怨国人在技术图书方面抄来抄去,不求甚解,虽然出版图书者甚众,但最终成为精品者却凤毛麟角.于是,更多读者热衷于外版书.但显然,并非所有国人的外语水平都足以在阅读原版书籍时毫无障碍.那么退而求其次,寻求翻译版就成为一种看似不得已的选择. 不幸的是,网上对于翻译版书籍的吐槽可以说从未消停.我也看过

日期之差

日期之差 问题描述 已知2011年11月11日是星期五,问YYYY年MM月DD日是星期几?注意考虑闰年的情况.尤其是逢百年不闰,逢400年闰的情况. 输入格式 输入只有一行 YYYY MM DD 输出格式 输出只有一行 W 数据规模和约定 1599 <= YYYY <= 2999 1 <= MM <= 12 1 <= DD <= 31,且确保测试样例中YYYY年MM月DD日是一个合理日期 1 <= W <= 7,分别代表周一到周日 样例输入 2011 11

最低点差(欧美最低1个点差),支持ECN账户

最低点差(欧美最低1个点差),支持ECN账户Welcome账户开户成功就送8美元. 让你0投入开始外汇实盘之路.更重要的一点是,开户完全在网上搞定,在网上填写申请表,提供国内身份证明和地址证明的扫描件,很快就搞定了. 特点:1.点差低,欧美EURUSD点差只要1到2个点差.2.可通过工商或建设网银0手续费入金,入金金额不限制,可以是5美元,也可以50美元,没有其他外汇公司的电汇就100多美元的手续费.也没有最低入金200美元这样的限制 3.可以交易迷你单,最低可以下0.01手.4.杠杆最大1:5

asp.net(C#)时间相减 得到天数、小时、分钟、秒差

asp.net(C#)时间相减 得到天数.小时.分钟.秒差 DateTime dtone = Convert.ToDateTime("2007-1-1 05:00:00"); DateTime dtwo = Convert.ToDateTime("2007-1-5 08:00:00"); TimeSpan span = dtone.Subtract(dtwo); //算法是dtone 减去 dtwo tss.Text = span.Days + "天&qu