https://pintia.cn/problem-sets/994805046380707840/exam/problems/1518582895035215872

题意

给你一棵树,给定树根,要求树的所有结点编号的dfs序中逆序对的数量总和,对结果模 \(10^9 + 7\)

树的结点数 \(\leq 3*10^5\)

思路

首先会想到,树的dfs序的方案数是 \(\prod_{i=1}^{n}cntson[i]\)

接下来分析什么情况下树的dfs序会产生逆序对。

把会产生逆序对的情况分为两种,第一种是两个点是祖先和子孙的关系,那么如果祖先更大,这一对点一定会产生逆序对,对答案的贡献是dfs序的方案数

第二种是两个点不是祖先和子孙的关系,又因为每个点的编号互不相同,所以它们有1/2的概率会产生逆序对,对答案的贡献是dfs序的方案数/2

那么最后的答案就是 第一种情况的数量 * 第一种情况的点对贡献 + 第二种情况的数量 * 第二种情况的点对贡献

统计第一种情况的数量:需要知道一个点的祖先中有多少比它大,可以在dfs结点时模拟一个栈,当遍历到某个点就把它入栈,遍历子结点时它就在栈中,遍历完子节点后把它出栈,然后用树状数组统计数量

第二类点,只用分析一个父亲结点的子树的情况,然后会发现它就包含了所有第二类情况

code

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 3e5 + 10, mod = 1e9 + 7;
int n, r;
int a[N];
vector<int> e[N];
ll fac[N], base, c[N], s, s2;
int sz[N]; // 第二类点:不是祖先也不是子孙的点 ll qpow(ll a,ll b){
ll ans=1;
while(b){
if(b%2){
ans*=a;
ans%=mod;
}
a*=a;
a%=mod;
b/=2;
}
return ans;
} inline int lowbit(int x) {return x & -x;} void upd(int x, ll k){
while(x<=n){
c[x]+=k;
x+=lowbit(x);
}
} ll sum(int x){
ll res=0;
while(x){
res+=c[x];
x-=lowbit(x);
}
return res;
} void init(int n) {
fac[0] = 1;
for(int i = 1; i <= n; i++) fac[i] = fac[i - 1] * i % mod;
} void dfs(int u, int fa) {
sz[u] = 1;
s = (s + sum(n) - sum(u)) % mod;
upd(u, 1);
ll t = 0;//
int cn = 0;
for(auto v : e[u]) {
if(v == fa) continue;
dfs(v, u);
sz[u] += sz[v];
cn++;
s2 += t * sz[v]; s2 %= mod;
t += sz[v];
}
base = base * fac[cn] % mod;
upd(u, -1);
} int main() {
scanf("%d%d", &n, &r);
init(n);
for(int i = 1, u, v; i < n; i++) {
scanf("%d%d", &u, &v);
e[u].push_back(v);
e[v].push_back(u);
}
base = 1;
dfs(r, 0);
ll ans = s * base % mod;
// ans = (ans + (1ll * n * (n - 1) / 2 - s - s2) * base % mod * qpow(2, mod - 2) % mod) % mod;
ans = (ans + s2 * base % mod * qpow(2, mod - 2) % mod) % mod;
printf("%lld\n", ans);
// cout << "base: " << base << endl;
system("pause");
return 0;
}

CCCC L3-032 关于深度优先搜索和逆序对的题应该不会很难吧这件事 【树状数组】的更多相关文章

  1. POJ 2299 Ultra-QuickSort 求逆序数 (归并或者数状数组)此题为树状数组入门题!!!

    Ultra-QuickSort Time Limit: 7000MS   Memory Limit: 65536K Total Submissions: 70674   Accepted: 26538 ...

  2. hdu 5147 Sequence II (树状数组 求逆序数)

    题目链接 Sequence II Time Limit: 5000/2500 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  3. Codeforces Round #261 (Div. 2) D. Pashmak and Parmida's problem (树状数组求逆序数 变形)

    题目链接 题意:给出数组A,定义f(l,r,x)为A[]的下标l到r之间,等于x的元素数.i和j符合f(1,i,a[i])>f(j,n,a[j]),求i和j的种类数. 我们可以用map预处理出  ...

  4. HDU 1394 Minimum Inversion Number ( 树状数组求逆序数 )

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1394 Minimum Inversion Number                         ...

  5. POJ3928Ping pong[树状数组 仿逆序对]

    Ping pong Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 3109   Accepted: 1148 Descrip ...

  6. HDU 1394 Minimum Inversion Number(最小逆序数/暴力 线段树 树状数组 归并排序)

    题目链接: 传送门 Minimum Inversion Number Time Limit: 1000MS     Memory Limit: 32768 K Description The inve ...

  7. 51nod1019逆序数(归并排序/树状数组)

    题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1019 题意:中文题诶- 思路: 方法1:归并排序- 归并排序过 ...

  8. POJ 2299 Ultra-QuickSort 逆序数 树状数组 归并排序 线段树

    题目链接:http://poj.org/problem?id=2299 求逆序数的经典题,求逆序数可用树状数组,归并排序,线段树求解,本文给出树状数组,归并排序,线段树的解法. 归并排序: #incl ...

  9. HDU 4911 (树状数组+逆序数)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4911 题目大意:最多可以交换K次,就最小逆序对数 解题思路: 逆序数定理,当逆序对数大于0时,若ak ...

  10. POJ2299Ultra-QuickSort(归并排序 + 树状数组求逆序对)

    树状数组求逆序对   转载http://www.cnblogs.com/shenshuyang/archive/2012/07/14/2591859.html 转载: 树状数组,具体的说是 离散化+树 ...

随机推荐

  1. JZOJ 1040. 【GDOI2007】夏娜的菠萝包

    状压玩疯了 \(Code\) #include<cstdio> #include<iostream> #include<cstring> using namespa ...

  2. python之路76 路飞项目 企业项目类型、软件开发流程、路飞项目需求、pip永久换源、虚拟环境、路飞项目前后端创建、包导入、后端项目目录调整

    知识获取渠道 cnblogs csdn 掘金 思否 找工作app boss直骗.拉钩.智联.猎聘.脉脉(内推,hr). 企业项目类型 1.面向互联网用户:商城类项目 微信小程序商城 2.面向互联网用户 ...

  3. Linux命令-用户、权限管理

      Linux命令-用户.权限管理 用户是Unix/Linux系统工作中重要的一环,用户管理包括用户与组账号的管理. 在Unix/Linux系统中,不论是由本机或是远程登录系统,每个系统都必须拥有一个 ...

  4. 一个更适合Java初学者的轻量级开发工具:BlueJ

    Java是世界上最流行的编程语言之一,它被广泛用于从Web开发到移动应用的各种应用程序.大部分Java工程师主要是用IDEA.Eclipse为主,这两个开发工具由于有强大的能力,所以复杂度上就更高一些 ...

  5. Blender如何设置模型中心点

    推荐:将 NSDT场景编辑器 加入你的3D开发工具链. 在使用Blender建模的时候,有时候会导入一些从别的地方**过来的模型,这时候就会遇到一个问题,模型放到场景中时与鼠标放置的位置有一定的偏差, ...

  6. Spring Boot 整合 Logback 日志

    Spring Boot 支持 Java Util Logging,Log4J,Log4J2 和 Logback 等日志框架,默认采用 Logback 日志. 在实际 Spring Boot 项目中使用 ...

  7. Spark 要点总结及优化

    Spark Components:  角色组成: Driver :  由SparkContext创建,运行在main方法,负责资源申请与调度,程序分发,接收每个分区的计算结果 Cluster mana ...

  8. gridfs + nginx + mongodb 实现图片服务器

    项目预览网址 : http://trans.waibaobao.cn/file/pics 安装:前提安装mongodb 作为文件储存库 1)nginx-gridfs安装 a.安装所用依赖包 yum - ...

  9. 洛谷P4726 【模板】多项式指数函数(多项式 exp)

    题目 https://www.luogu.com.cn/problem/P4726 思路 (略) 是个板题,但是包含了很多多项式的基础板子,适合用来练手. 据说递归版的好写(好抄),但是我猜测和fft ...

  10. vue 利用xlsx、xlsx-style、file-saver实现前端导出excel表格 (包括设置单元格居中、边框等样式) antdesignvue、elementui、vxetable 等都适用

    我用的方法是在表格的根组件外层赋一个div用来导出整个表格,所以antdesignvue.elementui.vxetable 或者原生的table写法应该全都适用,此处我用的框架为antdesign ...