bzoj 3772 :精神污染 线段树+打标记 or 主席树
3772: 精神污染
Time Limit: 10 Sec Memory Limit: 64 MB
Submit: 315 Solved: 87
[Submit][Status][Discuss]
Description
Input
Output
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#define LL long long
#define ls x*2,l,mid
#define rs x*2+1,mid+1,r
#define N 200005
using namespace std;
LL gcd(LL a,LL b)
{
if(!b)return a;
return gcd(b,a%b);
}
int n,m;
int head[N],ver[N*],nxt[N*],tot;
void add(int a,int b)
{
tot++;nxt[tot]=head[a];head[a]=tot;ver[tot]=b;return ;
}
int dep[N],fa[N][],dfn[N],z,ed[N];
void dfs(int x,int f)
{
dfn[x]=++z;
for(int i=head[x];i;i=nxt[i])
{
if(ver[i]==f)continue;
dep[ver[i]]=dep[x]+;
fa[ver[i]][]=x;
dfs(ver[i],x);
}ed[x]=z;
}
void yu()
{
for(int i=;i<=;i++)
{
for(int j=;j<=n;j++)
{
fa[j][i]=fa[fa[j][i-]][i-];
}
}return ;
}
int lca(int x,int y)
{
if(dep[x]<dep[y])swap(x,y);
for(int i=;i>=;i--)
{
if(dep[fa[x][i]]>=dep[y])x=fa[x][i];
}
if(x==y)return x;
for(int i=;i>=;i--)
{
if(fa[x][i]!=fa[y][i])
{
x=fa[x][i];y=fa[y][i];
}
}
return fa[x][];
}
int a[N*];
void add(int x,int l,int r,int pos,int z)
{
if(l==r)
{
a[x]+=z;
return ;
}
int mid=(l+r)>>;
if(pos<=mid)add(ls,pos,z);
else add(rs,pos,z);
a[x]=a[x*]+a[x*+];
}
int qur(int x,int l,int r,int ll,int rr)
{
if(ll>rr)return ;
if(ll<=l&&rr>=r)
{
return a[x];
}
int mid=(l+r)>>;
if(ll>mid)return qur(rs,ll,rr);
if(rr<=mid)return qur(ls,ll,rr);
return qur(rs,ll,rr)+qur(ls,ll,rr);
}
struct qr
{
int x,y;
}q[N];
struct node
{
int op,y;
node(int xx,int yy)
{
op=xx;y=yy;
}
};
int faa(int x,int y)
{
for(int i=;i>=;i--)
{
if(dep[fa[x][i]]>dep[y])x=fa[x][i];
}
return x;
}
vector<node>lazy[N];
LL ans;
int sb[N];
void dp(int x,int f)
{
for(int i=;i<lazy[x].size();i++)
{
if(!lazy[x][i].op)continue;
if(lazy[x][i].op==)
{
ans-=qur(,,n,dfn[lazy[x][i].y],ed[lazy[x][i].y]);
}
else
{
int yy=lazy[x][i].y;
int now=faa(x,yy);
ans-=qur(,,n,,dfn[now]-)+qur(,,n,ed[now]+,n);
if(x==yy)
{
ans-=qur(,,n,dfn[x],dfn[x]);
}
}
}
for(int i=;i<lazy[x].size();i++)
{
add(,,n,dfn[lazy[x][i].y],);
if(lazy[x][i].op==)
{
int uu=lca(x,lazy[x][i].y);
sb[uu]++;
}
}
for(int i=head[x];i;i=nxt[i])
{
if(ver[i]==f)continue;
dp(ver[i],x);
}
for(int i=;i<lazy[x].size();i++)
{
if(!lazy[x][i].op)continue;
if(lazy[x][i].op==)
{
ans+=qur(,,n,dfn[lazy[x][i].y],ed[lazy[x][i].y]);
}
else
{
int yy=lazy[x][i].y;
int now=faa(x,yy);
if(x==yy)
{
ans+=qur(,,n,dfn[x],dfn[x]);
ans+=sb[x];
}
ans+=qur(,,n,,dfn[now]-)+qur(,,n,ed[now]+,n);
}
}
}
int main()
{
scanf("%d%d",&n,&m);
int t1,t2;
for(int i=;i<n;i++)
{
scanf("%d%d",&t1,&t2);
add(t1,t2);add(t2,t1);
}
ans=-m;
dep[]=;
dfs(,-);
yu();
for(int i=;i<=m;i++)
{
scanf("%d%d",&q[i].x,&q[i].y);
int tmp=lca(q[i].x,q[i].y);
if(tmp==q[i].x)
{
lazy[q[i].y].push_back(node(,q[i].x));
if(q[i].x!=q[i].y)lazy[q[i].x].push_back(node(,q[i].y));
}
else if(tmp==q[i].y)
{
lazy[q[i].y].push_back(node(,q[i].x));
lazy[q[i].x].push_back(node(,q[i].y));
}
else
{
lazy[q[i].x].push_back(node(,q[i].y));
lazy[q[i].y].push_back(node(,q[i].x));
}
}
dp(,-);
LL tt=(LL)m*(m-)/;
LL oo=gcd(tt,ans);
printf("%lld/%lld\n",ans/oo,tt/oo);
return ;
}
bzoj 3772 :精神污染 线段树+打标记 or 主席树的更多相关文章
- bzoj 3772 精神污染 主席树+dfs序
精神污染 Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 637 Solved: 177[Submit][Status][Discuss] Descri ...
- BZOJ 3772: 精神污染(dfs序+主席树)
传送门 解题思路 比较神仙的一道题.首先计算答案时可以每条路径所包含的路径数,对于\(x,y\)这条路径,可以在\(x\)这处开个\(vector\)存\(y\),然后计算时只需要算这个路径上每个点的 ...
- BZOJ 3772: 精神污染 (dfs序+树状数组)
跟 BZOJ 4009: [HNOI2015]接水果一样- CODE #include <set> #include <queue> #include <cctype&g ...
- BZOJ 1901 Zju2112 Dynamic Rankings ——树状数组套主席树
[题目分析] BZOJ这个题目抄的挺霸气. 主席树是第一时间想到的,但是修改又很麻烦. 看了别人的题解,原来还是可以用均摊的思想,用树状数组套主席树. 学到了新的姿势,2333o(* ̄▽ ̄*)ブ [代 ...
- BZOJ 2141 排队(树状数组套主席树)
解法很多的题,可以块套树状数组,可以线段树套平衡树.我用的是树状数组套主席树. 题意:给出一段数列,m次操作,每次操作是交换两个位置的数,求每次操作后的逆序对数.(n,m<=2e4). 对于没有 ...
- [poj2104]可持久化线段树入门题(主席树)
解题关键:离线求区间第k小,主席树的经典裸题: 对主席树的理解:主席树维护的是一段序列中某个数字出现的次数,所以需要预先离散化,最好使用vector的erase和unique函数,很方便:如果求整段序 ...
- [bzoj3196][Tyvj1730]二逼平衡树_树套树_位置线段树套非旋转Treap/树状数组套主席树/权值线段树套位置线段树
二逼平衡树 bzoj-3196 Tyvj-1730 题目大意:请写出一个维护序列的数据结构支持:查询给定权值排名:查询区间k小值:单点修改:查询区间内定值前驱:查询区间内定值后继. 注释:$1\le ...
- BZOJ 3439: Kpm的MC密码 (trie+dfs序主席树)
题意 略 分析 把串倒过来插进trietrietrie上, 那么一个串的kpmkpmkpm串就是这个串在trietrietrie上对应的结点的子树下面的所有字符串. 那么像 BZOJ 3551/354 ...
- BZOJ 3196 Tyvj 1730 二逼平衡树 ——树状数组套主席树
[题目分析] 听说是树套树.(雾) 怒写树状数组套主席树,然后就Rank1了.23333 单点修改,区间查询+k大数查询=树状数组套主席树. [代码] #include <cstdio> ...
随机推荐
- dom学习要点
Dom操作 1.文本内容操作 - innerText:操作文本 - innerHtml:操作全内容 //innerText标签: <div id='i2' ><a>土味程序员& ...
- 2019第十届蓝桥杯 E题 迷宫
/*输入 30 50 01010101001011001001010110010110100100001000101010 00001000100000101010010000100000001001 ...
- Metasploit拿Shell
进入metasploit系统 msfconsole Nmap端口扫描 nmap –sV IP(或者域名),如果机器设置有防火墙禁ping,可以使用nmap -P0(或者-Pn) –sV IP(或者域名 ...
- 6.openldap客户端安装
作者:yaoyao 1.账号登录系统流程讲解 当在客户端输入账号登录系统时.系统根据/etc/nsswitch.conf配置文件获取账号查找顺序,然后在根据pam配置文件调用相关模块,对账号/etc/ ...
- 第九次psp例行报告
本周psp 本周进度条 代码累积折线图 博文字数累积折线图 饼状图
- Daily Scrum6 11.10
今日任务: 徐钧鸿:codingcook的sql相关内容,并在进行复查张艺:继续用户管理部分代码黄可嵩:学习搜索的知识,继续进行搜索的移植和响应徐方宇:动态控件和页面间信息传递以及页面响应事件机制试验 ...
- C#获取周一、周日的日期 函数类
#region 得到一周的周一和周日的日期 /// <summary> /// 计算本周的周一日期 /// </summary> ...
- 2018软工实践—Beta冲刺(2)
队名 火箭少男100 组长博客 林燊大哥 作业博客 Beta 冲鸭鸭! 成员冲刺阶段情况 林燊(组长) 过去两天完成了哪些任务 协调组内工作 修改前端界面 展示GitHub当日代码/文档签入记录(组内 ...
- Leetcode题库——11.盛最多水的容器
@author: ZZQ @software: PyCharm @file: maxArea.py @time: 2018/10/11 21:47 说明:给定 n 个非负整数 a1,a2,...,an ...
- [2017BUAA软工]第1次个人作业
软工第1次个人作业 一.快速看完整部教材,列出你不懂的5-10个问题,发布在你的个人博客上. 1.文中提到"积累问题领域的知识和经验(例如:对医疗或金融行业的了解)."然而我们如何 ...