4229: 选择

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 67  Solved: 41

Description

现在,我想知道自己是否还有选择。
给定n个点m条边的无向图以及顺序发生的q个事件。
每个事件都属于下面两种之一:
1、删除某一条图上仍存在的边
2、询问是否存在两条边不相交的路径可以从点u出发到点v

Input

第一行三个整数n,m,q
接下来m行,每行两个整数u,v,表示u和v之间有一条边
接下来q行,每行一个大写字母o和2个整数u、v,依次表示按顺序发生的q个事件:
当o为’Z’时,表示删除一条u和v之间的边
当o为’P’时,表示询问是否存在两条边不相交的路径可以从点u出发到点v

Output

对于每组询问,如果存在,输出Yes,否则输出No

Sample Input

7 8 7
1 2
1 3
1 4
2 3
3 4
3 7
7 4
5 6
Z 1 4
P 1 3
P 2 4
Z 1 3
P 1 3
Z 6 5
P 5 6

Sample Output

Yes
Yes
No
No

HINT

对于全部数据,max(n,m,q)<=100000

Source

【分析】

  我的做法跟BZOJ 1969大致一样【我改了改代码交的。。

  这题没说删完的图联通,所以最后还要处理一下。。

  然后每次询问x到y的关键边数量是否为0就好了。

  【详细做法见BZOJ 1969

 #include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define Maxn 100010
#define Maxm 100010 struct node
{
int x,y,next;
int bj,id;
}t[Maxn*],tt[Maxm*];
int first[Maxn],len; void ins(int x,int y)
{
// printf("%d -> %d\n",x,y);
t[++len].x=x;t[len].y=y;
t[len].next=first[x];first[x]=len;
} struct nnode
{
int l,r,lc,rc,sm;
}tr[Maxn*]; void upd(int x)
{
if(tr[x].l==tr[x].r||tr[x].sm!=) return;
int lc=tr[x].lc,rc=tr[x].rc;
tr[lc].sm=tr[rc].sm=;
} int tot;
int build(int l,int r)
{
int x=++tot;
tr[x].l=l;tr[x].r=r;
if(l!=r)
{
int mid=(l+r)>>;
tr[x].lc=build(l,mid);
tr[x].rc=build(mid+,r);
}
else tr[x].lc=tr[x].rc=;
tr[x].sm=r-l+;
return x;
} void change(int x,int l,int r)
{
if(tr[x].l==l&&tr[x].r==r)
{
tr[x].sm=;
return;
}
upd(x);
int mid=(tr[x].l+tr[x].r)>>,lc=tr[x].lc,rc=tr[x].rc;
if(r<=mid) change(lc,l,r);
else if(l>mid) change(rc,l,r);
else
{
change(lc,l,mid);
change(rc,mid+,r);
}
tr[x].sm=tr[lc].sm+tr[rc].sm;
} int query(int x,int l,int r)
{
if(tr[x].sm==) return ;
if(tr[x].l==l&&tr[x].r==r) return tr[x].sm;
upd(x);
int mid=(tr[x].l+tr[x].r)>>,lc=tr[x].lc,rc=tr[x].rc;
if(r<=mid) return query(lc,l,r);
else if(l>mid) return query(rc,l,r);
else return query(lc,l,mid)+query(rc,mid+,r);
} int tp[Maxn],sum[Maxn],son[Maxn],dfn[Maxn],dep[Maxn];
int ff[Maxn];
int cnt;
void dfs(int x,int f)
{
son[x]=;sum[x]=;dep[x]=dep[f]+;
ff[x]=f;
for(int i=first[x];i;i=t[i].next) if(t[i].y!=f)
{
int y=t[i].y;
dfs(y,x);
sum[x]+=sum[y];
if(son[x]==||sum[son[x]]<sum[y]) son[x]=y;
}
} void dfs2(int x,int tpp)
{
dfn[x]=++cnt;tp[x]=tpp;
if(son[x]) dfs2(son[x],tpp);
for(int i=first[x];i;i=t[i].next) if(t[i].y!=ff[x]&&t[i].y!=son[x])
{
int y=t[i].y;
dfs2(y,y);
}
} void fchange(int x,int y)
{
while(tp[x]!=tp[y])
{
if(dep[tp[x]]<dep[tp[y]]) swap(x,y);
change(,dfn[tp[x]],dfn[x]);
x=ff[tp[x]];
}
if(dep[x]<dep[y]) swap(x,y);
if(x!=y) change(,dfn[y]+,dfn[x]);
} int fquery(int x,int y)
{
int ans=;
while(tp[x]!=tp[y])
{
if(dep[tp[x]]<dep[tp[y]]) swap(x,y);
ans+=query(,dfn[tp[x]],dfn[x]);
x=ff[tp[x]];
}
if(dep[x]<dep[y]) swap(x,y);
if(x!=y)
{
// if(dfn[y]+1>dfn[x]) while(1);
ans+=query(,dfn[y]+,dfn[x]);
}
return ans;
} int fa[Maxn];
int ffa(int x)
{
if(fa[x]!=x) fa[x]=ffa(fa[x]);
return fa[x];
} bool cmp(node x,node y)
{
if(x.x==y.x&&x.y==y.y) return x.bj<y.bj;
return (x.x==y.x)?(x.y<y.y):(x.x<y.x);
}
bool cmp2(node x,node y) {return x.id<y.id;} int ans[Maxn]; char s[]; void solve()
{
int n,m,q;
scanf("%d%d%d",&n,&m,&q);
int ll=;
for(int i=;i<=m;i++)
{
int x,y;
ll++;
scanf("%d%d",&tt[ll].x,&tt[ll].y);
if(tt[ll].x>tt[ll].y) swap(tt[ll].x,tt[ll].y);
tt[ll].bj=;//cha ru
}
int ct=;
while(q--)
{
scanf("%s",s);
ll++;
scanf("%d%d",&tt[ll].x,&tt[ll].y);
if(tt[ll].x>tt[ll].y) swap(tt[ll].x,tt[ll].y);
if(s[]=='Z') tt[ll].bj=-;//shan chu
else tt[ll].bj=;//xun wen
tt[ll].id=++ct;
}
sort(tt+,tt++ll,cmp);
for(int i=;i<=n;i++) fa[i]=i;
ct++;
int pp=;
for(int i=;i<=ll;i++)
{
if(tt[i].bj==) continue;
if(tt[i].bj==)
{
if(pp==||tt[i].x!=tt[pp].x||tt[i].y!=tt[pp].y)
{
if(ffa(tt[i].x)==ffa(tt[i].y))
{
tt[i].bj=-;
tt[i].id=ct;
}
else
{
ins(tt[i].x,tt[i].y);
ins(tt[i].y,tt[i].x);
fa[ffa(tt[i].x)]=tt[i].y;
}
}
}
pp=i;
}
sort(tt+,tt++ll,cmp2);
for(int i=ll;i>=;i--) if(tt[i].bj==-)
{
if(ffa(tt[i].x)!=ffa(tt[i].y))
{
ins(tt[i].x,tt[i].y);
ins(tt[i].y,tt[i].x);
fa[ffa(tt[i].x)]=tt[i].y;
tt[i].bj=;
}
}
dep[]=;cnt=;
for(int i=;i<=n;i++) if(ffa(i)==i)
{
dfs(i,);
dfs2(i,i);
}
build(,n); ans[]=;
for(int i=ll;i>=;i--)
{
if(tt[i].bj==) continue;
if(tt[i].bj==-)
{
fchange(tt[i].x,tt[i].y);
}
else
{
if(ffa(tt[i].x)!=ffa(tt[i].y)) ans[++ans[]]=-;
else ans[++ans[]]=fquery(tt[i].x,tt[i].y);
}
}
for(int i=ans[];i>=;i--)
{
if(ans[i]==) printf("Yes\n");
else printf("No\n");
}
} int main()
{
solve();
return ;
}

【是不是打的有点丑

2017-03-27 10:33:13

【BZOJ 4229】 4229: 选择 (线段树+树链剖分)的更多相关文章

  1. 线段树&数链剖分

    傻逼线段树,傻逼数剖 线段树 定义: 线段树是一种二叉搜索树,与区间树相似,它将一个区间划分成一些单元区间,每个单元区间对应线段树中的一个叶结点. 使用线段树可以快速的查找某一个节点在若干条线段中出现 ...

  2. UOJ#30/Codeforces 487E Tourists 点双连通分量,Tarjan,圆方树,树链剖分,线段树

    原文链接https://www.cnblogs.com/zhouzhendong/p/UOJ30.html 题目传送门 - UOJ#30 题意 uoj写的很简洁.清晰,这里就不抄一遍了. 题解 首先建 ...

  3. BZOJ1758[Wc2010]重建计划——分数规划+长链剖分+线段树+二分答案+树形DP

    题目描述 输入 第一行包含一个正整数N,表示X国的城市个数. 第二行包含两个正整数L和U,表示政策要求的第一期重建方案中修建道路数的上下限 接下来的N-1行描述重建小组的原有方案,每行三个正整数Ai, ...

  4. [LOJ3014][JOI 2019 Final]独特的城市——树的直径+长链剖分

    题目链接: [JOI 2019 Final]独特的城市 对于每个点,它的答案最大就是与它距离最远的点的距离. 而如果与它距离为$x$的点有大于等于两个,那么与它距离小于等于$x$的点都不会被计入答案. ...

  5. CF487E Tourists 圆方树、树链剖分

    传送门 注意到我们需要求的是两点之间所有简单路径中最小值的最小值,那么对于一个点双联通分量来说,如果要经过它,则一定会经过这个点双联通分量里权值最小的点 注意:这里不能缩边双联通分量,样例\(2\)就 ...

  6. BZOJ 1758 / Luogu P4292 [WC2010]重建计划 (分数规划(二分/迭代) + 长链剖分/点分治)

    题意 自己看. 分析 求这个平均值的最大值就是分数规划,二分一下就变成了求一条长度在[L,R]内路径的权值和最大.有淀粉质的做法但是我没写,感觉常数会很大.这道题可以用长链剖分做. 先对树长链剖分. ...

  7. 2019.01.08 codeforces 1009F. Dominant Indices(长链剖分)

    传送门 长链剖分模板题. 题意:给出一棵树,设fi,jf_{i,j}fi,j​表示iii的子树中距离点iii距离为jjj的点的个数,现在对于每个点iii要求出使得fif_ifi​取得最大值的那个jjj ...

  8. 【LOJ】#3014. 「JOI 2019 Final」独特的城市(长链剖分)

    LOJ#3014. 「JOI 2019 Final」独特的城市(长链剖分) 显然我们画一条直径,容易发现被统计的只可能是直径某个距离较远的端点到这个点的路径上的值 用一个栈统计可以被统计的点,然后我们 ...

  9. BZOJ.1036 [ZJOI2008]树的统计Count ( 点权树链剖分 线段树维护和与最值)

    BZOJ.1036 [ZJOI2008]树的统计Count (树链剖分 线段树维护和与最值) 题意分析 (题目图片来自于 这里) 第一道树链剖分的题目,谈一下自己的理解. 树链剖分能解决的问题是,题目 ...

  10. BZOJ 3672: [Noi2014]购票( 树链剖分 + 线段树 + 凸包 )

    s弄成前缀和(到根), dp(i) = min(dp(j) + (s(i)-s(j))*p(i)+q(i)). 链的情况大家都会做...就是用栈维护个下凸包, 插入时暴力弹栈, 查询时就在凸包上二分/ ...

随机推荐

  1. 如何写出高性能SQL语句

    优化SQL查询:如何写出高性能SQL语句 1.首先要搞明白什么叫执行计划? 执行计划是数据库根据SQL语句和相关表的统计信息作出的一个查询方案,这个方案是由查询优化器自动分析产生欀如一条SQL语句如果 ...

  2. How to reset XiaoMi bluetooth headphone Youth edition.

    To reset the speaker 1. Long press the phone call button to shut off the speaker 2. Connect the char ...

  3. 使用 pjax 载入的新页面,新页面上 类方法 无法被触发?

    在父页面上有定义类似 $(".class").click(function(){ ... }) 经过pjax 载入后的新页面 点击后没有触发事件 在segmentfault 上提问 ...

  4. VC调用易语言DLL

    易语言方面: .版本 .子程序 show, , 公开 ' 本名称子程序用作测试程序用,仅在开发及调试环境中有效,编译发布程序前将被系统自动清空,请将所有用作测试的临时代码放在本子程序中. ***注意不 ...

  5. Where can I check in?

    Where can I check in? 在哪儿办理登记手续?

  6. python进阶之内置函数和语法糖触发魔法方法

    前言 前面已经总结了关键字.运算符与魔法方法的对应关系,下面总结python内置函数对应的魔法方法. 魔法方法 数学计算 abs(args):返回绝对值,调用__abs__; round(args): ...

  7. redis的备份恢复

    说明:默认rdb方式保存,redis支持主从和哨兵等,但是在某些情况下我们会单机跑,所以有时候我们就会需要设计到备份恢复 环境:原始redis:192.168.1.200 新redis:192.168 ...

  8. vsts 自动部署到Azure

    如果要部署到中国区的Azure ,请先阅读 http://www.cnblogs.com/cnryb/p/7867275.html 前置条件,我把代码托管在vsts(放在GitHub上也没问题,这里不 ...

  9. centos 6.5配置ftp服务器,亲测可用

    设置开机启动 1 chkconfig vsftpd on 启动服务 1 /sbin/service vsftpd start 配置FTP用户组/用户以及相应权限 添加用户组 1 groupadd ft ...

  10. django时差8个小时问题

    问题现象: 在用django做好的网站,上传图片后显示的发布时间比当前时间差了8小时 查找问题: 查看服务器系统时间,经查与当前时间一致,无问题 查看数据库中的时间也一样 最终原因: 在setting ...