题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6200

题意:给个图,有2种操作,一种是加一条无向边,二是查询u,v之间必须有的边的条数,所谓必须有的边就是对于u,v必须通过这条边才能到达。

解法:一个很简单的想法,搞出图上的一颗树,然后剩下的边当成询问点队加到更新点集,每加入一个更新点对,直接把u,v区间的值置为0即可,查询就直接区间求和,可以直接树剖来维护,简单暴力,读入挂卡过。还有1个log的做法,可以用LCT维护(这个没写,口胡的)

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5+5;
typedef long long LL;
struct edge{
int to,next;
edge(){}
edge(int to,int next):to(to),next(next){}
}E[maxn*2];
struct FastIO
{
static const int S = 1310720;
int wpos;
char wbuf[S];
FastIO() : wpos(0) {}
inline int xchar()
{
static char buf[S];
static int len = 0, pos = 0;
if (pos == len)
pos = 0, len = fread(buf, 1, S, stdin);
if (pos == len) return -1;
return buf[pos ++];
}
inline int xuint()
{
int c = xchar(), x = 0;
while (c <= 32) c = xchar();
for (; '0' <= c && c <= '9'; c = xchar()) x = x * 10 + c - '0';
return x;
}
inline int xint()
{
int s = 1, c = xchar(), x = 0;
while (c <= 32) c = xchar();
if (c == '-') s = -1, c = xchar();
for (; '0' <= c && c <= '9'; c = xchar()) x = x * 10 + c - '0';
return x * s;
}
inline void xstring(char *s)
{
int c = xchar();
while (c <= 32) c = xchar();
for (; c > 32; c = xchar()) * s++ = c;
*s = 0;
}
inline void wchar(int x)
{
if (wpos == S) fwrite(wbuf, 1, S, stdout), wpos = 0;
wbuf[wpos ++] = x;
}
inline void wint(LL x)
{
if (x < 0) wchar('-'), x = -x;
char s[24];
int n = 0;
while (x || !n) s[n ++] = '0' + x % 10, x /= 10;
while (n--) wchar(s[n]);
}
inline void wstring(const char *s)
{
while (*s) wchar(*s++);
}
~FastIO()
{
if (wpos) fwrite(wbuf, 1, wpos, stdout), wpos = 0;
}
} io;
int n, m, head[maxn],edgecnt, tim;
int sz[maxn], top[maxn], son[maxn], dep[maxn];
int fa[maxn],tid[maxn];
void init(){
memset(head,-1,sizeof(head));
memset(son,-1,sizeof(son));
edgecnt=tim=0;
}
void add(int u,int v){
E[edgecnt].to=v,E[edgecnt].next=head[u],head[u]=edgecnt++;
}
void dfs1(int u, int father, int d){
dep[u]=d;
fa[u]=father;
sz[u]=1;
for(int i=head[u]; i+1; i=E[i].next){
int v=E[i].to;
if(v!=father){
dfs1(v,u,d+1);
sz[u]+=sz[v];
if(son[u]==-1||sz[v]>sz[son[u]]) son[u]=v;
}
}
}
void dfs2(int u, int tp){
top[u]=tp;
tid[u]=++tim;
if(son[u]==-1) return;
dfs2(son[u],tp);
for(int i=head[u];i+1;i=E[i].next){
int v=E[i].to;
if(v!=son[u]&&v!=fa[u])
dfs2(v,v);
}
}
namespace DSU{
int fa1[maxn];
void init1(){
for(int i=1; i<maxn; i++) fa1[i]=i;
}
int find_set(int x){
if(x==fa1[x]) return x;
else return fa1[x] = find_set(fa1[x]);
}
bool union_set(int x, int y){
x = find_set(x);
y = find_set(y);
if(x!=y){
fa1[x]=y;
return 1;
}
else{
return 0;
}
}
}
using namespace DSU;
namespace SegmentTree{
int sum[maxn<<2], lazy[maxn<<2];
void pushup(int rt){
sum[rt]=sum[rt*2]+sum[rt*2+1];
}
void pushdown(int rt){
if(lazy[rt]){
lazy[rt*2]=lazy[rt];
lazy[rt*2+1]=lazy[rt];
sum[rt*2]=sum[rt*2+1]=0;
lazy[rt]=0;
}
}
void build(int l, int r, int rt){
lazy[rt] = 0;
if(l == r){
sum[rt] = l!=1;
return;
}
int mid = (l+r)/2;
build(l,mid,rt*2);
build(mid+1,r,rt*2+1);
pushup(rt);
}
void update(int L, int R, int l, int r, int rt){
if(L<=l&&r<=R){
lazy[rt]=1;
sum[rt]=0;
return;
}
pushdown(rt);
int mid=(l+r)/2;
if(L<=mid) update(L,R,l,mid,rt*2);
if(mid<R) update(L,R,mid+1,r,rt*2+1);
pushup(rt);
}
int query(int L, int R, int l, int r, int rt){
if(L<=l&&r<=R) return sum[rt];
int mid=(l+r)/2;
pushdown(rt);
int ret=0;
if(L<=mid) ret+=query(L,R,l,mid,rt*2);
if(mid<R) ret+=query(L,R,mid+1,r,rt*2+1);
return ret;
}
void update(int u, int v){
while(top[u]!=top[v]){
if(dep[top[u]]<dep[top[v]]) swap(u,v);
update(tid[top[u]], tid[u], 1, tim, 1);
u = fa[top[u]];
}
if(u == v) return;
if(dep[u]<dep[v]) swap(u,v);
update(tid[v]+1,tid[u],1,tim,1);
}
int query(int u, int v){
int ret=0;
while(top[u]!=top[v]){
if(dep[top[u]]<dep[top[v]]) swap(u,v);
ret += query(tid[top[u]], tid[u], 1, tim, 1);
u = fa[top[u]];
}
if(u==v) return ret;
if(dep[u]<dep[v]) swap(u,v);
ret += query(tid[v]+1,tid[u],1,tim,1);
return ret;
}
}
using namespace SegmentTree;
int main()
{
int T,q,ks=0;
T = io.xint();
while(T--){
printf("Case #%d:\n", ++ks);
n = io.xint();
m = io.xint();
init();
init1();
vector <pair<int, int> > G;
for(int i=1; i<=m; i++){
int u, v;
u = io.xint();
v = io.xint();
if(union_set(u,v)){
add(u, v);
add(v, u);
}else{
G.emplace_back(u, v);
}
}
dfs1(1,0,0);
dfs2(1,1);
build(1,n,1);
for(auto &it:G){
update(it.first,it.second);
}
q = io.xint();
for(int i=1; i<=q; i++){
int op,x,y;
op = io.xint();
x = io.xint();
y = io.xint();
if(op==1)
update(x, y);
else{
printf("%d\n", query(x,y));
}
}
}
return 0;
}

HDU 6200 2017沈阳网络赛 树上区间更新,求和的更多相关文章

  1. HDU 6203 2017沈阳网络赛 LCA,DFS+树状数组

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6203 题意:n+1 个点 n 条边的树(点标号 0 ~ n),有若干个点无法通行,导致 p 组 U V ...

  2. HDU 6201 2017沈阳网络赛 树形DP或者SPFA最长路

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6201 题意:给出一棵树,每个点有一个权值,代表商品的售价,树上每一条边上也有一个权值,代表从这条边经过 ...

  3. HDU 6199 2017沈阳网络赛 DP

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6199 题意:n堆石子,Alice和Bob来做游戏,一个人选择取K堆那么另外一个人就必须取k堆或者k+1 ...

  4. HDU 6205 2017沈阳网络赛 思维题

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6205 题意:给你n堆牌,原本每一堆的所有牌(a[i]张)默认向下,每次从第一堆开始,将固定个数的牌(b ...

  5. HDU 6198 2017沈阳网络赛 线形递推

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6198 题意:给出一个数k,问用k个斐波那契数相加,得不到的数最小是几. 解法:先暴力打表看看有没有规律 ...

  6. HDU 6195 2017沈阳网络赛 公式

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6195 题意:有M个格子,有K个物品.我们希望在格子与物品之间连数量尽可能少的边,使得——不论是选出M个 ...

  7. HDU 6197 array array array 2017沈阳网络赛 LIS

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6197 题意:给你n个数,问让你从中删掉k个数后(k<=n),是否能使剩下的序列为非递减或者非递增 ...

  8. HDU 6194 string string string 2017沈阳网络赛 后缀数组

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6194 题意:告诉你一个字符串和k , 求这个字符串中有多少不同的子串恰好出现了k 次. 解法:后缀数组 ...

  9. HDU 6194 string string string ——(2017沈阳网络赛,后缀数组)

    思路见:http://blog.csdn.net/aozil_yang/article/details/77929216. 代码如下: #include <stdio.h> #includ ...

随机推荐

  1. swift 录制多个音频 并将音频转换为mp3 并合成多个mp3文件为一个文件

    我的需求是可以录制多个文件,最后生成的文件格式为mp3形式,查了下各种资料,因为swift无法直接将音频录制为mp3格式,所以最后我采取的解决方案为先将每个单独的文件转为mp3,最后逐一合并形成一个m ...

  2. 教你用python写:HDU刷题神器

    声明:本文以学习为目的,请不要影响他人正常判题 HDU刷题神器,早已被前辈们做出来了,不过没有见过用python写的.大一的时候见识了学长写这个,当时还是一脸懵逼,只知道这玩意儿好屌-.时隔一年,决定 ...

  3. Python数据可视化Matplotlib——Figure画布背景设置

    之前在今日头条中更新了几期的Matplotlib教学短视频,在圈内受到了广泛好评,现应大家要求,将视频中的代码贴出来,方便大家学习. 为了使实例图像显得不单调,我们先将绘图代码贴上来,此处代码对Fig ...

  4. js获取url,截取url参数,截取url后文件名

    获取当前: var url = window.location.href; 百度为例: var url=window.location.href; console.info(url); http:// ...

  5. Hello world! My first blog!

    Hello world! My first blog!

  6. 社群系统 ThinkSNS+ 中如何利用 Laravel 表单验证来验证用户名的?(我朝独有需求,两个字母占一个汉字。。。)

    ThinkSNS+后端框架使用laravel,每周和 laravel master 保持同步,而后台和 html 5 则采用 vue 开发.语言特性方面,采用 php 7 的严格模式. 言归正传,之所 ...

  7. db2 表关联查询

    今天在MapReduce的练习中看到了一个题目: file: CHILD PARENT ---------- ---------- tom lucy tom jack jone lucy jone j ...

  8. 三种Join方法

    NESTED LOOP JOIN  (NLJOIN) 对于被连接的数据子集较小的情况,nested loop连接是个较好的选择.nested loop就是扫描一个表,每读到一条记录,就根据索引去另一个 ...

  9. 【leetcode】260. Single Number III

    Given an array of numbers nums, in which exactly two elements appear only once and all the other ele ...

  10. Java面经 面试经验 互联网公司面试经验 后端面试经验

    应聘相关 声明: 1,程序员相关的哈 2,万事无定论,比如说,就算你小学毕业,但是java基础却扎实到变态,我相信open的公司还是会给你机会的. 3,心态很重要,虽然日常的心态不容易控制,面试那俩小 ...