并查集加线段树合并
线下测试点1数据可以过,其他在线ide也能正常输出,但是提交和洛谷的ide都无法输出qwq
5WA 5RE
代码如下
#include<bits/stdc++.h>
using namespace std;
const int N = 2e5+100;
int n, m, q_op;
int fa[N],root[N*4], ls[N*4], rs[N*4];
int tot, sum[N*4];
int v[N];
int id_to[N];
int read()
{
int x = 0, f = 1;char ch = getchar();
while(ch<'0'||ch>'9') {if(ch == '-') f = -1;ch = getchar(); }
while(ch>='0'&&ch<='9'){x = x*10+ch-'0'; ch = getchar();}
return x*f;
}
int merge(int now, int lst, int l, int r)//线段树合并模板,now 当前节点 lst 上一个节点
{
if(!now||!lst) return now | lst;
if(l == r)
{
sum[now] +=sum[lst];
return now;
}
int mid = (l+r)>>1;
ls[now] = merge(ls[now], ls[lst], l,mid ), rs[now] = merge(rs[now], rs[lst],mid+1, r);
sum[now]+=sum[lst];
return now;
}
void change(int l, int r, int p, int &tr, int v)
{
if(!tr) tr = ++ tot;
sum[tr]+=v;
if(l == r) return;
int mid = (l+r)>>1;
if(p<=mid) change(l, mid, p, ls[tr], v);
else change(mid+1, r, p, rs[tr], v);
}
int find(int x)
{
if(x!=fa[x]) fa[x] = find(fa[x]);
return fa[x];
}
int search(int tr, int kk, int l, int r)
{
if(sum[tr]<kk) return -1;
if(l == r) return l;
int mid = (l+r)>>1;
if(sum[ls[tr]]>=kk) return search(ls[tr], kk, l, mid);
else return search(rs[tr], kk-sum[ls[tr]], mid+1, r);
}
int main()
{
n = read(), m = read();
for(int i = 1; i<=n; i++)
{
v[i] = read();
id_to[v[i]] = i;
change(1, n, v[i],root[i],1 );
}
for(int i = 1; i<=n; i++) fa[i] = i;
for(int i = 1; i<=m; i++)
{
int u, v;
u = read(), v = read();
int pp = find(u);
int qq = find(v);
if(pp == qq) continue;
fa[qq] = pp;
root[qq] = merge(root[pp], root[qq], 1, n);
}
q_op = read();
for(int i = 1; i<=q_op; i++)
{
char op;
scanf("%c ", &op);
if(op == 'Q')
{
int u, k;
u = read(), k = read();
int pp = find(u);
int ans = search(root[pp], k, 1, n);
if(ans == -1) printf("%d\n", ans);
else printf("%d\n", id_to[ans]);
}
else
{
int u, v;
u = read(), v = read();
int pp = find(u);
int qq = find(v);
if(pp == qq) continue;
fa[qq] = pp;
root[qq] = merge(root[pp], root[qq], 1, n);
}
}
return 0;
}