【线段树】【扫描线】小睿睿的方案
很精彩的一道题!题意还是很清晰的。自己想了半天没有思路,最后参考了题解。
首先问题可以变成所有方案数(n∗(n−1)2\frac{n*(n-1)}{2}2n∗(n−1))减去非法方案数。
考虑每对情侣对方案的负贡献:
当不考虑重复时,
当两个结点非祖先-后代关系时,贡献也就是两个子树的大小的乘积。
当两个结点为祖先-后代关系时,贡献为后代的子树与(所有点,除了祖先指向后代的儿子的子树)的乘积
考虑用一n*n的初始为0的矩阵来表示每一个方案,矩阵上(i,j)或(j,i)点为正数表示i与j的方案是不合法的,那么用dfs序来映射点,一个点的子树的dfs序连续,每个贡献可以表示为若干矩形区域,那么用线段树+扫描线即可计算出不合法的方案数。简单来说,按行从小到大扫描,如果碰到一个贡献矩形的上边缘,则加入贡献矩形左边缘到右边缘为1,如果碰到一个贡献矩形的下边缘之下一层,则加入贡献矩形左边缘到右边缘为-1,也就是线段树区间加法。然后查询只要看第一个节点值就行了。
线段树的T记录为正数的点数,也就是是扫描到第i行时,与深搜序为i的那个点形成的非法方案数。而addv记录区间的修改。
注意,这里线段树不需要标记下传。原因在于某个点的值是否为正数,只和它到线段树根节点的路径上是否存在addv>0有关(因为修改的对称性,addv不可能为负数),不再有时效性,只要存在就相当于被覆盖了,因此默认从根节点向下扫描,如果addv>0,下面的T和addv就不用关心,这个区间都是被覆盖了。
当然,如果不是很放心,写个标记下传也可以的。
#include <cstdio>
#include<algorithm>
#include<vector>#define kl (k<<1)
#define kr (k<<1|1)
#define M (L+R>>1)
#define lin L,M
#define rin M+1,R
using namespace std;
using LL=long long;struct item
{int l,r,d;item(int l=0,int r=0,int d=0) : l(l),r(r),d(d){}
}ask;int n,m,dfn[100005],sons[100005],dfs_clock;
int dep[100005],p[100005][17],u,v;
vector<int> E[100005];
vector<item> Q[100005];
int T[1<<18],addv[1<<18];
LL ans;void dfs(int x,int fa)
{dfn[x]=++dfs_clock;sons[x]=1;for(int i:E[x])if(i!=fa){dep[i]=dep[x]+1;p[i][0]=x;for(int j=1;1<<j<=dep[i];j++)p[i][j]=p[p[i][j-1]][j-1];dfs(i,x),sons[x]+=sons[i];}
}void fun(int la,int ra,int lb,int rb)
{if(lb<rb){Q[la].emplace_back(lb,rb-1,1);Q[ra].emplace_back(lb,rb-1,-1);}if(la<ra){Q[lb].emplace_back(la,ra-1,1);Q[rb].emplace_back(la,ra-1,-1);}
}int find_son_of_u(int x,int y)
{int i;for(i=0;1<<i<=dep[y]-dep[x];i++);i--;for(int j=i;j>=0;j--)if(1<<j<dep[y]-dep[x])y=p[y][j];return y;
}void modify(int k,int L,int R)
{if(ask.l<=L&&R<=ask.r){addv[k]+=ask.d;if(addv[k]>0)T[k]=R-L+1;elseT[k]=L<R?T[kl]+T[kr]:0;return;}if(ask.l<=M)modify(kl,lin);if(ask.r>M)modify(kr,rin);T[k]=addv[k]>0?R-L+1:T[kl]+T[kr];
}int main()
{scanf("%d%d",&n,&m);for(int i=1;i<n;i++)scanf("%d%d",&u,&v),E[u].push_back(v),E[v].push_back(u);dfs(1,0);while(m--){scanf("%d%d",&u,&v);if(dep[u]>dep[v])swap(u,v);int tmp=find_son_of_u(u,v);if(p[tmp][0]==u){fun(1,dfn[tmp],dfn[v],dfn[v]+sons[v]);fun(dfn[tmp]+sons[tmp],n+1,dfn[v],dfn[v]+sons[v]);}elsefun(dfn[u],dfn[u]+sons[u],dfn[v],dfn[v]+sons[v]);}for(int i=1;i<=n;i++){for(auto &t:Q[i])ask=t,modify(1,1,n);ans+=T[1];}printf("%lld",(LL) n*(n-1)-ans>>1);return 0;
}
【线段树】【扫描线】小睿睿的方案相关推荐
- 线段树扫描线求矩形周长详解
线段树扫描线求矩形周长详解 原创 wucstdio 最后发布于2018-04-24 16:12:09 阅读数 841 收藏 发布于2018-04-24 16:12:09 版权声明:本文为博主原创文章, ...
- hdu3255 线段树扫描线求体积
题意: 给你n个矩形,每个矩形上都有一个权值(该矩形单位面积的价值),矩形之间可能重叠,重叠部分的权值按照最大的算,最后问这n个矩形组成的图形的最大价值. 思路: 线段树扫描线 ...
- hdu1542 线段树扫描线求矩形面积的并
题意: 给你n个正方形,求出他们的所占面积有多大,重叠的部分只能算一次. 思路: 自己的第一道线段树扫描线题目,至于扫描线,最近会写一个总结,现在就不直接在这里写了,说下我的方 ...
- hdu 1542 Atlantis (线段树+扫描线)
http://acm.hdu.edu.cn/showproblem.php?pid=1542 单纯的线段树+扫描线求面积并,需要离散化. code: #include <cstdlib> ...
- HDU 1264 Counting Squares (线段树-扫描线-矩形面积并)
版权声明:欢迎关注我的博客.本文为博主[炒饭君]原创文章,未经博主同意不得转载 https://blog.csdn.net/a1061747415/article/details/25471349 P ...
- bzoj 1645: [Usaco2007 Open]City Horizon 城市地平线(线段树扫描线)
1645: [Usaco2007 Open]City Horizon 城市地平线 Time Limit: 5 Sec Memory Limit: 64 MB Submit: 732 Solved: ...
- 亚特兰蒂斯【线段树+扫描线+离散化】
亚特兰蒂斯[线段树+扫描线+离散化] POJ1151.ACwing247 题目: 有几个古希腊书籍中包含了对传说中的亚特兰蒂斯岛的描述. 其中一些甚至包括岛屿部分地图. 但不幸的是,这些地图描述了亚特 ...
- 2016 UESTC Training for Data Structures F - 郭大侠与“有何贵干?” CDOJ 1335 线段树 扫描线 离散化
F - 郭大侠与"有何贵干?" 就是给一个三维空间,和N个长方体,问覆盖K次的体积 x和y都是1e9,但是z是[1,3],所以可以把这个分为两个二维平面,求被覆盖K次的面积,最后加 ...
- hdu 3265 线段树扫描线(拆分矩形)
题意: 给你n个矩形,每个矩形上都有一个矩形的空洞,所有的矩形都是平行于x,y轴的,最后问所有矩形的覆盖面积是多少. 思路: 是典型的矩形覆盖问题,只不过每个矩形上多了一个矩 ...
- 线段树/扫描线问卷调查反馈——Rmq Problem / mex(主席树),Boring Queries(二分+st表+主席树),Colorful Squares(扫描线)
文章目录 Rmq Problem / mex Boring Queries Colorful Squares Rmq Problem / mex luogu4137 对aia_iai建权值线段树 再 ...
最新文章
- 面试造飞机系列:用心整理的HashMap面试题,以后都不用担心了
- ggplot2 图形排版:patchwork 包简单入门
- vc6.0 简易的tcp网络讲解(二)
- windows远程桌面管理工具下载_vnc viewer 64位下载,3步实现vnc viewer 64位下载
- 洛谷 P3853 [TJOI2007]路标设置
- c语言的boolean_0基础学习C语言第四章:三种基本结构
- PHP笔记-JavaScript中使用Smarty变量
- NopCommerce(Core)学习目录
- c++用向量给句子排序_用C ++对向量排序
- 如意淘商品推荐技术介绍之一:基础推荐
- 52类110个主流的Java框架
- po、bo、do、dto、vo相关图形
- 展台设计:企业展台搭建都有哪些途径?
- 计算机基础:调整显示器分辨率及刷新率
- 使用 Java 8 语言功能
- Ajax登录注册-----数据请求 交互
- C语言:练习3-8 查询水果价格.2021-07-19
- 监控视频压缩2—Block-Composed Background Reference for High Efficiency Video Coding
- MGW PCI Framework Architecture
- 有理函数积分方法以及待定系数法的无解问题