您的位置:首页 > 其它

codeforces 85D. Sum of Medians(线段树or分块)

2017-03-03 15:02 459 查看

题目链接:codeforces 85D. Sum of Medians

题意:

 add x 表示向集合中添加x(添加x的时候保证x是第一次被添加入集合)
del x 表示从集合中删除x (删除x的时候保证x存在于集合中)
sum 将集合排序后,询问集合里面所有下标i % 5 = 3的元素的和(如果集合为空输出0)  题解: 线段树的每一个节点维护5个值,表示这个区间%5的和,然后开一个mov数组表示这个区间向后移了多少位。 注意的是每次插入一个数,要先将[i+1,r]向后移一个区间后,在把数插进去,这样答案才不会错。
1 #include<bits/stdc++.h>
2 #define ls l,m,rt<<1
3 #define rs m+1,r,rt<<1|1
4 #define mst(a,b) memset(a,b,sizeof(a))
5 #define F(i,a,b) for(int i=a;i<=b;++i)
6 using namespace std;
7 typedef long long ll;
8 typedef pair<int,int>P;
9
10 const int N=1e5+7;
11 int n,hsh
,h_ed,x,ed,cnt,sqr;//sqr为每个块的大小
12 P q
;
13 char op[10];
14
15 int getid(int x){return lower_bound(hsh+1,hsh+1+h_ed,x)-hsh;}
16
17 struct kuai
18 {
19     int l,r;
20     set<int>dt;
21     ll sum[5];
22     kuai()
23     {
24         l=r=0;
25         dt.clear(),mst(sum,0);
26     }
27 }s[501];
28
29 ll ask()
30 {
31     ll ans=0;
32     int mov=0;
33     F(i,1,cnt)
34     {
35         ans+=s[i].sum[(5-mov+3)%5];
36         mov=(mov+s[i].dt.size())%5;
37     }
38     return ans;
39 }
40
41 void add(int op,int x)
42 {
43     int now=x/sqr+(x%sqr!=0),ct=0;
44     if(op==1)s[now].dt.insert(hsh[x]);
45     else s[now].dt.erase(hsh[x]);
46     set<int>::iterator it;
47     mst(s[now].sum,0);
48     for(it=s[now].dt.begin();it!=s[now].dt.end();it++)
49         ct++,s[now].sum[ct%5]+=*it;
50 }
51
52 int main(){
53     scanf("%d",&n);
54     F(i,1,n)
55     {
56         scanf("%s",op);
57          if(op[0]=='s')q[i]=P(0,0);
58          else
59          {
60              scanf("%d",&x);
61              q[i]=P(op[0]=='a'?1:-1,x);
62              hsh[++ed]=x;
63          }
64     }
65     sort(hsh+1,hsh+1+ed),h_ed=unique(hsh+1,hsh+1+ed)-hsh-1;
66     sqr=sqrt(h_ed+0.5);
67     if(sqr)cnt=h_ed/sqr+(h_ed%sqr!=0);//注意只有sum的情况
68     F(i,1,n)if(!q[i].first)printf("%lld\n",ask());
69         else add(q[i].first,getid(q[i].second));
70     return 0;
71 }
View Code

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: