Processing math: 7%

CF85D Sum of Medians

CF85D Sum of Medians

题意翻译

一个集合,初始为空。现有三个操作:

1.add:向集合里加入数x,保证加入前集合中没有数x;

2.del:从集合中删除数x,保证删除前集合中有x;

3.sum:询问将集合里的数从小到大排序后,求下标i模5余3的数的和。

现有n次操作,对于每个查询操作,输出答案


 

题解Here!

一开始感觉好不可做啊。。。

然后发现,线段树好像可以搞一搞。

线段树每个节点维护5个值,即区间中所有\text{下标}\mod5后结果相同的位置的值的和。

即:在区间[l,r]上维护:

\sum_{i=l}^rv_i[i\mod 5==0],\sum_{i=l}^rv_i[i\mod 5==1],\sum_{i=l}^rv_i[i\mod 5==2],\sum_{i=l}^rv_i[i\mod 5==3],\sum_{i=l}^rv_i[i\mod 5==4]

再维护区间中有多少个值num

合并的时候左子树不动,右子树中所有\text{下标}\mod5==x的位置应该是((i-num)\%5+5)\%5

至于线段树怎么动态加点。。。

其实离线一下就可以把线段树搞成静态,然后离散化一下就好。

记得开long\ long

还与就是在CF上是不能用\%lld来读入、输出long\ long,所以还是老老实实用cin,cout。。。

附代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
#include<iostream>
#include<algorithm>
#include<cstdio>
#define LSON rt<<1
#define RSON rt<<1|1
#define DATA(x,k) a[x].data[k]
#define NUM(x) a[x].num
#define LSIDE(x) a[x].l
#define RSIDE(x) a[x].r
#define MAXN 100010
using namespace std;
int n,m=0;
int lsh[MAXN];
struct Question{
    int f,x;
}que[MAXN];
struct Segment_Tree{
    long long data[5];
    int num,l,r;
}a[MAXN<<2];
inline int read(){
    int date=0,w=1;char c=0;
    while(c<'0'||c>'9'){if(c=='-')w=-1;c=getchar();}
    while(c>='0'&&c<='9'){date=date*10+c-'0';c=getchar();}
    return date*w;
}
inline void pushup(int rt){
    NUM(rt)=NUM(LSON)+NUM(RSON);
    for(int i=0;i<5;i++)DATA(rt,i)=DATA(LSON,i)+DATA(RSON,((i-NUM(LSON))%5+5)%5);
}
void buildtree(int l,int r,int rt){
    LSIDE(rt)=l;RSIDE(rt)=r;NUM(rt)=0;
    if(l>=r)return;
    int mid=l+r>>1;
    buildtree(l,mid,LSON);
    buildtree(mid+1,r,RSON);
}
void update(int k,int c,long long v,int rt){
    if(LSIDE(rt)==RSIDE(rt)){
        DATA(rt,1)+=v;
        NUM(rt)+=c;
        return;
    }
    int mid=LSIDE(rt)+RSIDE(rt)>>1;
    if(k<=mid)update(k,c,v,LSON);
    else update(k,c,v,RSON);
    pushup(rt);
}
void work(){
    for(int i=1,x;i<=n;i++){
        if(que[i].f==1){
            x=lower_bound(lsh+1,lsh+m+1,que[i].x)-lsh;
            update(x,1,que[i].x,1);
        }
        else if(que[i].f==-1){
            x=lower_bound(lsh+1,lsh+m+1,que[i].x)-lsh;
            update(x,-1,-que[i].x,1);
        }
        else cout<<DATA(1,3)<<endl;
    }
}
void init(){
    char ch[2];
    n=read();
    for(int i=1,x;i<=n;i++){
        scanf("%s",ch);
        if(ch[0]=='a'){
            x=read();
            lsh[++m]=que[i].x=x;
            que[i].f=1;
        }
        else if(ch[0]=='d'){
            x=read();
            que[i].x=x;
            que[i].f=-1;
        }
        else que[i].f=0;
    }
    sort(lsh+1,lsh+m+1);
    m=unique(lsh+1,lsh+m+1)-lsh-1;
    buildtree(1,m,1);
}
int main(){
    init();
    work();
    return 0;
}

 


其实还有一种更暴力的方法:

vector大法好!

各种STL乱搞就好。

附代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<vector>
using namespace std;
int n;
vector<int> a;
inline int read(){
    int date=0,w=1;char c=0;
    while(c<'0'||c>'9'){if(c=='-')w=-1;c=getchar();}
    while(c>='0'&&c<='9'){date=date*10+c-'0';c=getchar();}
    return date*w;
}
void work(){
    char ch[2];
    n=read();
    for(int i=1,x;i<=n;i++){
        scanf("%s",ch);
        if(ch[0]=='a'){
            x=read();
            a.insert(lower_bound(a.begin(),a.end(),x),x);
        }
        else if(ch[0]=='d'){
            x=read();
            a.erase(lower_bound(a.begin(),a.end(),x));
        }
        else{
            long long ans=0;
            for(int i=2;i<a.size();i+=5)ans+=a[i];
            cout<<ans<<endl;
        }
    }
}
int main(){
    work();
    return 0;
}

 

posted @   符拉迪沃斯托克  阅读(370)  评论(0编辑  收藏  举报
编辑推荐:
· 软件产品开发中常见的10个问题及处理方法
· .NET 原生驾驭 AI 新基建实战系列:向量数据库的应用与畅想
· 从问题排查到源码分析:ActiveMQ消费端频繁日志刷屏的秘密
· 一次Java后端服务间歇性响应慢的问题排查记录
· dotnet 源代码生成器分析器入门
阅读排行:
· ThreeJs-16智慧城市项目(重磅以及未来发展ai)
· 软件产品开发中常见的10个问题及处理方法
· Vite CVE-2025-30208 安全漏洞
· 互联网不景气了那就玩玩嵌入式吧,用纯.NET开发并制作一个智能桌面机器人(四):结合BotSharp
· MQ 如何保证数据一致性?
Live2D
欢迎阅读『CF85D Sum of Medians』
点击右上角即可分享
微信分享提示