社区讨论
求助 爆空间
P8496[NOI2022] 众数参与者 3已保存回复 3
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 3 条
- 当前快照
- 1 份
- 快照标识符
- @lo85udx7
- 此快照首次捕获于
- 2023/10/27 13:16 2 年前
- 此快照最后确认于
- 2023/10/27 13:16 2 年前
为什么我的做法会有几个点超空间
需要回收线段树合并后的节点吗?
CPP#include<iostream>
#include<queue>
#include<vector>
#define N 10000000
using namespace std;
vector <int>V[N];
int pre[N],root[N];
int Front[N],Last[N],t[N];
int n,q;
struct Node{
int l,r;
int ls,rs;
int w;
}tree[N];
queue <int>Q;
int cnt;
int build(int l,int r)
{
int id=++cnt;
tree[id].l=l,tree[id].r=r;
return id;
}
int m,Vsize;
void Insert(int now,int pos,int w)
{
if(tree[now].l==tree[now].r&&tree[now].l==pos)
{tree[now].w+=w;return ;}
int mid=(tree[now].l+tree[now].r)/2;
if(pos<=mid)
{
if(tree[now].ls==0) tree[now].ls=build(tree[now].l,mid);
Insert(tree[now].ls,pos,w);
}
else
{
if(tree[now].rs==0) tree[now].rs=build(mid+1,tree[now].r);
Insert(tree[now].rs,pos,w);
}
tree[now].w=(tree[tree[now].ls].w+tree[tree[now].rs].w);
}
int Query(int l,int r)
{
if(l==r)
{
int Size=0;
for(int i=1;i<=m;i++)
Size+=tree[t[i]].w;
if(Size>Vsize/2) return l;
return -1;
}
int Lsize=0,Rsize=0,mid=(l+r)/2;
for(int i=1;i<=m;i++)
Lsize+=tree[tree[t[i]].ls].w;
if(Lsize>Vsize/2)
{
for(int i=1;i<=m;i++)
t[i]=tree[t[i]].ls;
return Query(l,mid);
}
for(int i=1;i<=m;i++)
Rsize+=tree[tree[t[i]].rs].w;
if(Rsize>Vsize/2)
{
for(int i=1;i<=m;i++)
t[i]=tree[t[i]].rs;
return Query(mid+1,r);
}
return -1;
}
int merge(int x,int y)
{
if(!x||!y)
return x+y;
if(tree[x].l==tree[x].r)
{
tree[x].w+=tree[y].w;
return x;
}
tree[x].ls=merge(tree[x].ls,tree[y].ls);
tree[x].rs=merge(tree[x].rs,tree[y].rs);
tree[x].w=tree[tree[x].ls].w+tree[tree[x].rs].w;
return x;
}
int main()
{
ios::sync_with_stdio(false);
freopen("In.in","r",stdin);
freopen("Out.out","w",stdout);
cin>>n>>q;
for(int i=1;i<=n;i++)
{
int l;
cin>>l;
pre[i]=i,Front[i]=i,Last[i]=i;
root[i]=build(1,1000000);
for(int j=1;j<=l;j++)
{
int x;
cin>>x;
V[i].push_back(x);
Insert(root[i],x,1);
}
}
for(int i=1;i<=q;i++)
{
int id;
cin>>id;
if(id==1)
{
int x,y;
cin>>x>>y;
V[Last[x]].push_back(y);
Insert(root[x],y,1);
}
if(id==2)
{
int x;
cin>>x;
int k=V[Last[x]][V[Last[x]].size()-1];
Insert(root[x],k,-1);
V[Last[x]].pop_back();
if(V[Last[x]].empty())
Last[x]=pre[Last[x]];
}
if(id==3)
{
Vsize=0,cin>>m;
for(int j=1;j<=m;j++)
{
cin>>t[j];
t[j]=root[t[j]],Vsize+=tree[t[j]].w;
}
int Ans=Query(1,1000000);
cout<<Ans<<endl;
}
if(id==4)
{
int x,y,z;
cin>>x>>y>>z;
root[z]=merge(root[x],root[y]);
pre[Front[y]]=Last[x];
Front[z]=Front[x],Last[z]=Last[y];
}
}
}
回复
共 3 条回复,欢迎继续交流。
正在加载回复...