https://codeforces.com/problemset/problem/85/D

主要是操作三,排序,能不能做,之前写过用桶排序,看了一下ai值域太大做不了,再分析一下要求的量实际上就是,能不能直接求这个量,魔改区间和操作,写一个值域线段树这样ai就排序好了,接下来就判断a[i]是目前的第几个,考虑简单一点,全部操作完再回答sum,好像也没什么区别,直接维护区间(imod5==3)的和好了

发现最后的合并并不是 seg[id].val[1]=seg[tl(id)].val[1]+seg[tr(id)].val[1]
而是 seg[id].val[1]=seg[tl(id].val[1]+seg[tr(id)].val[(1-2+5)%5]
因此pushup魔改成 seg[id].val[i]=seg[tl(id].val[i]+seg[tr(id)].val[(i-l.sz+mod)%mod]
发现不止要维护val[3],val[3]也可以由其他val[i] i<5 转移来,维护vall[0-4]
ans=seg[1].val[3]
x<=1e9 离散化
离散化+权值线段树
code
// Problem: D. Sum of Medians
// Contest: Codeforces - Yandex.Algorithm 2011: Round 1
// URL: https://codeforces.com/problemset/problem/85/D
// Memory Limit: 256 MB
// Time Limit: 3000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
const int N=1e5+9;
const int mod=5;
struct Q{
int op,x;
}que[N];
vector<int> X;
int binary(int x){
return lower_bound(X.begin(),X.end(),x)-X.begin()+1;
}
//线段树
struct SEG{
#define INF (1<<31)
#define ll long long
#define tl(id) (id<<1)
#define tr(id) (id<<1|1)
#define li inline
struct node{
int l,r;
int sz;
ll val[5];
}seg[N<<2];
void pushup(node &id,node &l,node &r){
id.sz=l.sz+r.sz;
for(int i=0;i<=4;i++){
id.val[i]=l.val[i]+r.val[((i-l.sz)%mod+mod)%mod];
}
}
void pushup(int id){
pushup(seg[id],seg[tl(id)],seg[tr(id)]);
}
li int inrange(int L,int R,int l,int r){return l<=L && R<=r;}
li int outofrange(int L,int R,int l,int r){return L>r || R<l;}
li void update(int id,int l,int r,int pos,int v){
if(l==r){
seg[id].val[1]+=X[pos-1]*v;
seg[id].sz+=v;
return;
}
int mid=(l+r)>>1;
if(mid>=pos){
update(tl(id),l,mid,pos,v);
}else{
update(tr(id),mid+1,r,pos,v);
}
pushup(id);
}
}t;
int main(){
int n;
cin>>n;
for(int i=1;i<=n;i++){
string op;
cin>>op;
if(op=="add"){
int x;
cin>>x;
que[i].op=1;
que[i].x=x;
X.push_back(x);
}else if(op=="del"){
int x;
cin>>x;
que[i].op=2;
que[i].x=x;
X.push_back(x);
}else{
que[i].op=3;
que[i].x=0;
}
}
sort(X.begin(),X.end());
X.erase(unique(X.begin(),X.end()),X.end());
int xn=X.size();
for(int i=1;i<=n;i++){
if(que[i].op==1){
t.update(1,1,xn,binary(que[i].x),1);
}else if(que[i].op==2){
t.update(1,1,xn,binary(que[i].x),-1);
}else{
cout<<t.seg[1].val[3]<<'\n';
}
}
return 0;
}
311

被折叠的 条评论
为什么被折叠?



