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 ...
随机推荐
- 21. leetcode 492
492: 给定一个面积值,求它的长l和宽w.长和宽需满足:长大于等于宽,长和宽的差值尽可能小,长乘宽等于面积. 思路:先将l和w初始化为sqrt(area),然后看l*w是否等于面积,如果等于则返回l ...
- C#生成无重复的随机数
大一学期末的时候做课程设计时遇到过生成无重复随机数的问题,今天自己也写出来了: static int[] Create_Value() { Random ran = new Random(); //生 ...
- (6)UIView常见属性二
例如创建一个view视图,view是最纯洁的控制,必须得指定它的位置,而不像其他的控件像UISwitch默认都有一个位置 在viewDidLoad方法中打印它的位置: 将控件放入一个视图中,只需移动白 ...
- Github 开源:使用升讯威 Mapper( Sheng.Mapper)与 AutoMapper 互补,大幅提高开发效率!
Github 地址:https://github.com/iccb1013/Sheng.Mapper 在上一篇幅中,简单介绍了 升讯威 Mapper( Sheng.Mapper)[http://www ...
- M3
一,使用媒体查询的三种方式 1.直接在CSS中使用: @media 类型:(长选用all/screen)and (条件1)and(条件2){ CSS选择器{ CSS属性:属性值 } } ...
- 王佩丰第2讲-excel单元格格式设置 笔记
点小箭头都可以进入单元格格式设置 跨越合并 添加斜线 回车 ALT+ENTER 格式刷 数字格式 特定红色 货币VS会计专用 日期 2是1月2号,3是1月3号-- 自定义[例子中是在数值后面加&quo ...
- 社群系统 ThinkSNS+ 中如何利用 Laravel 表单验证来验证用户名的?(我朝独有需求,两个字母占一个汉字。。。)
ThinkSNS+后端框架使用laravel,每周和 laravel master 保持同步,而后台和 html 5 则采用 vue 开发.语言特性方面,采用 php 7 的严格模式. 言归正传,之所 ...
- AIX系统备份相关知识
AIX系统备份相关知识 --------------------------2013/10/16 预备知识.1.rootvg类似于windows中的C盘,即系统vg,这个vg上面当然也可以划分用户的逻 ...
- DB2 执行SQL脚本
今天有网友问到这个问题,平时也没怎么留意.刚刚做了测试在db2的SQL脚本中,直接写命令就好了. 例如: [db2inst1@win backups]$ cat test.ddl ---------- ...
- python 实现三级菜单
要求: 可选择进入各级子菜单 在各级菜单下可以选择退出 在子菜单下可以返回上一级菜单 Readme: 运行程序,输入菜单选项,进入对应的子菜单 # Joe Young data = { '山东':{ ...