Codeforces 85 D-Sum of Medians 【線段樹】

題目來源:https://codeforces.com/problemset/problem/85/D
在這裏插入圖片描述
在這裏插入圖片描述
★這題看輸入感覺是線段樹,但是寫的時候沒有一點思路。。。


題意:

有3種操作
1.添加一個數到集合中
2.刪除集合中的某個元素
3.輸出 集合排序後 序號mod5==3 的所有元素的

其中:不會往集合中添加 已經出現過的元素,也不會無緣無故刪去 集合中沒有的元素

思路:

本題解是通過 離線處理 的(即先保存所有步驟,再逐一處理)
保存步驟的過程中,記錄所有添加過的數,並進行 離散化處理 ,以此建立線段樹
每個子節點對應的是一個區間,很明顯這還不夠。我們要給 每一個區間存儲5個值,因爲模數是5
用數組sum[ maxn<<2 ][ 5 ]記錄,sum[ k ][ i ] 表示區間 k 的 序號mod5==i 的所有元素的和
通過 sum[k][i]=sum[k<<1][i]+sum[k<<1|1][(i-cnt[k<<1]%5+5)%5];來更新 就可求得結果


代碼:

#include<iostream>
#include<algorithm>
#include<string>
#include<vector>
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<deque>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
const int maxn=1e5+5;
const int sz=1<<6;
const int inf=2e9;
const int mod=1e9+7;
typedef long long LL;
int n,m;
int a[maxn],b[maxn],op[maxn];
LL cnt[maxn<<2],sum[maxn<<2][5];
template<class T>
inline void read(T &x)
{
    char c;x=1;
    while((c=getchar())<'0'||c>'9') if(c=='-') x=-1;
    T res=c-'0';
    while((c=getchar())>='0'&&c<='9') res=res*10+c-'0';
    x*=res;
}
void update(int k,int l,int r,int pos,int val,int opt)
{
    if(l==r){
        sum[k][0]+=val;
        cnt[k]+=opt;
        return ;
    }
    int mid=l+r>>1;
    if(mid>=pos) update(k<<1,l,mid,pos,val,opt);
    else update(k<<1|1,mid+1,r,pos,val,opt);
    cnt[k]=cnt[k<<1]+cnt[k<<1|1];
    for(int i=0;i<=4;i++){
        sum[k][i]=sum[k<<1][i]+sum[k<<1|1][(i-cnt[k<<1]%5+5)%5];
    }
}
int main()
{
    read(n);
    char s[10];
    m=0;
    for(int i=1;i<=n;i++){
        scanf("%s",s);
        if(s[0]=='a'){
            read(b[i]);
            op[i]=1;
            a[++m]=b[i];
        }
        else if(s[0]=='d'){
            read(b[i]);
            op[i]=-1;
        }
        else op[i]=0;
    }
    sort(a+1,a+m+1);
    m=unique(a+1,a+m+1)-a-1;
    for(int i=1;i<=n;i++){
        if(op[i]){
            int p=lower_bound(a+1,a+m+1,b[i])-a;
            update(1,1,m,p,b[i]*op[i],op[i]);
        }
        else{
            cout<<sum[1][2]<<endl;
        }
    }
    return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章