社区讨论
求卡常
P1110[ZJOI2007] 报表统计参与者 3已保存回复 4
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 4 条
- 当前快照
- 1 份
- 快照标识符
- @mhjhe714
- 此快照首次捕获于
- 2025/11/04 02:36 4 个月前
- 此快照最后确认于
- 2025/11/04 02:36 4 个月前
CPP
#include<bits/stdc++.h>
#define int long long
using namespace std;
inline string read(){
string str="";
char ch=getchar();
while(ch==' ' || ch=='\n' || ch=='\r') ch=getchar();
while(ch!=' ' && ch!='\n' && ch!='\r') str+=ch,ch=getchar();
return str;
}
inline int read1(){
int x=0;
char ch=getchar();
while(ch<'0'||ch>'9') ch=getchar();
while(ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();
return x;
}
const int N=5e5+5;
int n,m,w;
int a[N],b[N];
int root,tot,ans2=LLONG_MAX;
struct node{
int ls,rs,sz,sum,w;
}tree[N*5];
multiset<int> st;
void upd(int rt){
if(rt) tree[rt].sz=tree[tree[rt].ls].sz+tree[tree[rt].rs].sz+1;
}
void split(int rt,int v,int &x,int &y){
if(!rt) return x=y=0,void();
if(tree[rt].sum>v) y=rt,split(tree[rt].ls,v,x,tree[rt].ls);
else x=rt,split(tree[rt].rs,v,tree[rt].rs,y);
upd(rt);
}
void merge(int x,int y,int &rt){
if(!x||!y) rt=x+y;
else if(tree[x].w>=tree[y].w) rt=x,merge(tree[x].rs,y,tree[rt].rs);
else rt=y,merge(x,tree[y].ls,tree[rt].ls);
upd(rt);
}
void ins(int &rt,int x){
int rt1=0,rt2=0,k=++tot;
tree[tot]={0,0,1,x,rand()};
split(rt,x,rt1,rt2);
merge(rt1,k,rt1);
merge(rt1,rt2,rt);
}
void del(int &rt,int x){
int t1=0,t2=0,t3=0,t4=0,t5=0;
split(rt,x,t1,t2),split(t1,x-1,t3,t4);
merge(tree[t4].ls,tree[t4].rs,t4);
merge(t3,t4,t5),merge(t5,t2,rt);
}
int kth(int rt,int x){
int rt1=rt;
while(rt1){
if(tree[tree[rt1].ls].sz==x-1) return tree[rt1].sum;
else if(tree[tree[rt1].ls].sz>=x) rt1=tree[rt1].ls;
else x-=tree[tree[rt1].ls].sz+1,rt1=tree[rt1].rs;
}
return INT_MAX*3;
}
int pre(int rt,int x){
int rt1=0,rt2=0,res=0;
split(rt,x,rt1,rt2);
res=kth(rt1,tree[rt1].sz);
merge(rt1,rt2,rt);
return res;
}
int aft(int rt,int x){
int rt1=0,rt2=0,res=0;
split(rt,x-1,rt1,rt2);
res=kth(rt2,1);
merge(rt1,rt2,rt);
return res;
}
signed main(){
srand(time(0));
n=read1(),m=read1();
for(int i=1;i<=n;i++) a[i]=read1(),ins(root,a[i]);
for(int i=1;i<=n;i++){
if(i!=1) st.insert(abs(a[i]-a[i-1]));
del(root,a[i]);
int t1=pre(root,a[i]),t2=aft(root,a[i]);
ans2=min(ans2,min(abs(a[i]-t1),abs(t2-a[i])));
ins(root,a[i]);
b[i]=a[i];
}
while(m--){
string str;
str=read();
if(str=="INSERT"){
int x,y;
x=read1(),y=read1();
st.erase(st.find(abs(a[x+1]-b[x])));
st.insert(abs(y-b[x]));st.insert(abs(a[x+1]-y));
int t1=pre(root,y),t2=aft(root,y);
// cout<<t1<<" "<<t2<<endl;
ans2=min(ans2,min(abs(y-t1),abs(t2-y)));
b[x]=y;ins(root,y);
}
else if(str=="MIN_GAP") printf("%lld\n",*st.begin());
else printf("%lld\n",ans2);
}
return 0;
}
回复
共 4 条回复,欢迎继续交流。
正在加载回复...