任务统计
工作日刷题 ( 1 / 5 ) (1/5) (1/5)
链接
https://vjudge.net/problem/UVA-1455
题解
这题的横坐标完全没有什么用
把连线向
y
y
y轴投影可以得到一些线段,因为只有合并操作所以线段只会取并集,并查集维护一下连通性以及线段的上下端点,线段树维护每个点上线段的个数以及带权线段的权值和
这里可以标记永久化,因为是单点查询,所以可以简单地将从根节点到叶子节点这条路径上所有的标记求和
代码
#include <bits/stdc++.h>
#define maxn 1000010
using namespace std;
typedef long long ll;
struct segtree
{
segtree *lch, *rch;
ll l, r, add;
}pool[maxn<<3], *root1, *root2;
ll x[maxn], y[maxn], ndtot;
ll read(ll x=0)
{
ll c, f=1;
for(c=getchar();!isdigit(c);c=getchar())if(c=='-')f=-f;
for(;isdigit(c);c=getchar())x=x*10+c-48;
return f*x;
}
void segadd(segtree *p, ll l, ll r, ll v)
{
ll mid(p->l+p->r>>1);
if(l<=p->l and r>=p->r){p->add+=v;return;}
if(l<=mid)segadd(p->lch,l,r,v);
if(r>mid)segadd(p->rch,l,r,v);
}
ll getv(segtree *p, ll pos)
{
ll mid(p->l+p->r>>1);
if(p->l==p->r)return p->add;
if(pos<=mid)return getv(p->lch,pos)+p->add;
else return getv(p->rch,pos)+p->add;
}
void build(segtree *p, ll l, ll r)
{
ll mid(l+r>>1);
p->l=l, p->r=r;
p->add=0;
if(l==r)return;
build(p->lch=pool+ ++ndtot,l,mid);
build(p->rch=pool+ ++ndtot,mid+1,r);
}
struct UFSet
{
ll f[maxn], up[maxn], down[maxn], size[maxn];
ll find(ll x){return x==f[x]?x:f[x]=find(f[x]);}
void merge(ll x, ll y)
{
auto fx=find(x), fy=find(y);
if(size[fx]>size[fy])swap(x,y), swap(fx,fy);
up[fy]=max(up[fy],up[fx]);
down[fy]=min(down[fy],down[fx]);
size[fy]+=size[fx];
f[fx]=fy;
}
void init(ll n)
{
for(auto i=1;i<=n;i++)f[i]=i, size[i]=1, up[i]=down[i]=y[i];
}
}ufs;
int main()
{
ll T=read(), n, m, i;
while(T--)
{
ndtot=0;
n=read();
for(i=1;i<=n;i++)x[i]=read(), y[i]=read();
ufs.init(n);
build(root1=pool+ ++ndtot,0,1000000);
build(root2=pool+ ++ndtot,0,1000000);
m=read();
while(m--)
{
char s[10];
scanf("%s",s);
if(*s=='r')
{
auto a(read()+1), b(read()+1);
ll x, y;
if(ufs.find(a)!=ufs.find(b))
{
x=ufs.down[ufs.find(a)], y=ufs.up[ufs.find(a)];
if(x<y)segadd(root1,x,y-1,-1), segadd(root2,x,y-1,-ufs.size[ufs.find(a)]);
x=ufs.down[ufs.find(b)], y=ufs.up[ufs.find(b)];
if(x<y)segadd(root1,x,y-1,-1), segadd(root2,x,y-1,-ufs.size[ufs.find(b)]);
ufs.merge(a,b);
x=ufs.down[ufs.find(a)], y=ufs.up[ufs.find(a)];
if(x<y)segadd(root1,x,y-1,1), segadd(root2,x,y-1,ufs.size[ufs.find(a)]);
}
}
else
{
auto y(read()), _(read());
printf("%lld %lld\n",getv(root1,y),getv(root2,y));
}
}
}
return 0;
}