HDU 6200 2017沈阳网络赛 树上区间更新,求和
题目链接: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沈阳网络赛 树上区间更新,求和的更多相关文章
- HDU 6203 2017沈阳网络赛 LCA,DFS+树状数组
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6203 题意:n+1 个点 n 条边的树(点标号 0 ~ n),有若干个点无法通行,导致 p 组 U V ...
- HDU 6201 2017沈阳网络赛 树形DP或者SPFA最长路
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6201 题意:给出一棵树,每个点有一个权值,代表商品的售价,树上每一条边上也有一个权值,代表从这条边经过 ...
- HDU 6199 2017沈阳网络赛 DP
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6199 题意:n堆石子,Alice和Bob来做游戏,一个人选择取K堆那么另外一个人就必须取k堆或者k+1 ...
- HDU 6205 2017沈阳网络赛 思维题
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6205 题意:给你n堆牌,原本每一堆的所有牌(a[i]张)默认向下,每次从第一堆开始,将固定个数的牌(b ...
- HDU 6198 2017沈阳网络赛 线形递推
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6198 题意:给出一个数k,问用k个斐波那契数相加,得不到的数最小是几. 解法:先暴力打表看看有没有规律 ...
- HDU 6195 2017沈阳网络赛 公式
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6195 题意:有M个格子,有K个物品.我们希望在格子与物品之间连数量尽可能少的边,使得——不论是选出M个 ...
- HDU 6197 array array array 2017沈阳网络赛 LIS
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6197 题意:给你n个数,问让你从中删掉k个数后(k<=n),是否能使剩下的序列为非递减或者非递增 ...
- HDU 6194 string string string 2017沈阳网络赛 后缀数组
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6194 题意:告诉你一个字符串和k , 求这个字符串中有多少不同的子串恰好出现了k 次. 解法:后缀数组 ...
- HDU 6194 string string string ——(2017沈阳网络赛,后缀数组)
思路见:http://blog.csdn.net/aozil_yang/article/details/77929216. 代码如下: #include <stdio.h> #includ ...
随机推荐
- swift 录制多个音频 并将音频转换为mp3 并合成多个mp3文件为一个文件
我的需求是可以录制多个文件,最后生成的文件格式为mp3形式,查了下各种资料,因为swift无法直接将音频录制为mp3格式,所以最后我采取的解决方案为先将每个单独的文件转为mp3,最后逐一合并形成一个m ...
- 教你用python写:HDU刷题神器
声明:本文以学习为目的,请不要影响他人正常判题 HDU刷题神器,早已被前辈们做出来了,不过没有见过用python写的.大一的时候见识了学长写这个,当时还是一脸懵逼,只知道这玩意儿好屌-.时隔一年,决定 ...
- Python数据可视化Matplotlib——Figure画布背景设置
之前在今日头条中更新了几期的Matplotlib教学短视频,在圈内受到了广泛好评,现应大家要求,将视频中的代码贴出来,方便大家学习. 为了使实例图像显得不单调,我们先将绘图代码贴上来,此处代码对Fig ...
- js获取url,截取url参数,截取url后文件名
获取当前: var url = window.location.href; 百度为例: var url=window.location.href; console.info(url); http:// ...
- Hello world! My first blog!
Hello world! My first blog!
- 社群系统 ThinkSNS+ 中如何利用 Laravel 表单验证来验证用户名的?(我朝独有需求,两个字母占一个汉字。。。)
ThinkSNS+后端框架使用laravel,每周和 laravel master 保持同步,而后台和 html 5 则采用 vue 开发.语言特性方面,采用 php 7 的严格模式. 言归正传,之所 ...
- db2 表关联查询
今天在MapReduce的练习中看到了一个题目: file: CHILD PARENT ---------- ---------- tom lucy tom jack jone lucy jone j ...
- 三种Join方法
NESTED LOOP JOIN (NLJOIN) 对于被连接的数据子集较小的情况,nested loop连接是个较好的选择.nested loop就是扫描一个表,每读到一条记录,就根据索引去另一个 ...
- 【leetcode】260. Single Number III
Given an array of numbers nums, in which exactly two elements appear only once and all the other ele ...
- Java面经 面试经验 互联网公司面试经验 后端面试经验
应聘相关 声明: 1,程序员相关的哈 2,万事无定论,比如说,就算你小学毕业,但是java基础却扎实到变态,我相信open的公司还是会给你机会的. 3,心态很重要,虽然日常的心态不容易控制,面试那俩小 ...