现场赛大佬打印的代码,观摩了一哈。

写了注释,贴一下,好好学习。%%%PKU

代码:

 //树上差分(LCA)
#include<bits/stdc++.h> #define For(i,x,y) for (int i=x;i<y;i++)
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define lf else if #define dprintf(...) fprintf(stderr,__VA_ARGS__)
using namespace std; typedef long long ll;
typedef double db;
typedef pair<int,int> pii;
typedef vector<int> Vi; int IN(){//读入挂
int c,f,x;
while (!isdigit(c=getchar())&&c!='-');c=='-'?(f=,x=):(f=,x=c-'');
while (isdigit(c=getchar())) x=(x<<)+(x<<)+c-'';return !f?x:-x;
} const int p=1e9+;
const int N=3e5+; int Pow(int a,int b){//快速幂
int res=;
for (;b;b>>=,a=1ll*a*a%p) if (b&) res=1ll*res*a%p;
return res;
} struct Edge{
int y,nxt;
} E[N*];
int fac[N],inv[N];
int las[N],fa[][N],A[N],B[N],dep[N];
int n,m,cnt,x,y,z,ans,k; int C(int n,int m){//组合数
if (n<m) return ;
return 1ll*fac[n]*inv[m]%p*inv[n-m]%p;
} void Link(int x,int y){//链式前向星存图
E[cnt]=(Edge){y,las[x]};las[x]=cnt++;
E[cnt]=(Edge){x,las[y]};las[y]=cnt++;
} void dfs(int x){//LCA的dfs
for (int i=las[x],y;~i;i=E[i].nxt)
if ((y=E[i].y)!=fa[][x]){
fa[][y]=x;
dep[y]=dep[x]+;
dfs(y);
}
} int LCA(int x,int y){//LCA(ST)
if (dep[x]>dep[y]) swap(x,y);
for (int i=dep[y]-dep[x],k=;i;i>>=,k++) if(i&) y=fa[k][y];
if(x==y) return x;
for (int i=;~i;i--) if (fa[i][x]!=fa[i][y]) x=fa[i][x],y=fa[i][y];
return fa[][x];
} void Dfs(int x){//树上差分的dfs,从根节点深搜,回溯时将其本身的权值加上所有子节点的权值
for (int i=las[x],y;~i;i=E[i].nxt)
if ((y=E[i].y)!=fa[][x]){//筛掉父节点
Dfs(y);
A[x]+=A[y];//累加权值和
B[x]+=B[y];
}
} void Main(){
n=IN(),m=IN(),k=IN();
For(i,,n+) las[i]=-,A[i]=B[i]=;
cnt=;
For(i,,n) Link(IN(),IN());
dfs();
For(i,,) For(x,,n+) fa[i][x]=fa[i-][fa[i-][x]];
For(i,,m+){
x=IN(),y=IN();
z=LCA(x,y);
A[x]++,A[y]++,A[z]--,A[fa[][z]]--;
B[x]++,B[y]++,B[z]-=;//起点终点权值+1,lca权值-2
}
Dfs();
ans=;
// cout<<"--------"<<endl;
// for(int i=1;i<=n;i++)
// cout<<i<<" "<<A[i]<<endl;
// cout<<"--------"<<endl;
// for(int i=2;i<=n;i++)
// cout<<i<<" "<<B[i]<<endl;
// cout<<"--------"<<endl;
For(i,,n+){
ans=(ans+C(A[i],k))%p;
}
For(i,,n+){
ans=(ans-C(B[i],k)+p)%p;
}
printf("%d\n",ans);
} int main(){
fac[]=;
For(i,,N) fac[i]=1ll*fac[i-]*i%p;
inv[N-]=Pow(fac[N-],p-);
for(int i=N-;i;i--) inv[i-]=1ll*inv[i]*i%p;
for(int T=IN();T--;) Main();
} /*
1
3 6 2
1 2
1 3
1 1
2 2
3 3
1 2
1 3
2 3
*/

OK.

2018 icpc 徐州现场赛G-树上差分+组合数学-大佬的代码的更多相关文章

  1. 2018 ICPC 徐州网络赛

    2018 ICPC 徐州网络赛 A. Hard to prepare 题目描述:\(n\)个数围成一个环,每个数是\(0\)~\(2^k-1\),相邻两个数的同或值不为零,问方案数. solution ...

  2. 2018 icpc 徐州网络赛 F Features Track

    这个题,我也没想过我这样直接就过了 #include<bits/stdc++.h> using namespace std; ; typedef pair<int,int> p ...

  3. 【2018 ICPC焦作网络赛 G】Give Candies(费马小定理+快速幂取模)

    There are N children in kindergarten. Miss Li bought them N candies. To make the process more intere ...

  4. 2018 ICPC 沈阳网络赛

    2018 ICPC 沈阳网络赛 Call of Accepted 题目描述:求一个算式的最大值与最小值. solution 按普通算式计算方法做,只不过要同时记住最大值和最小值而已. Convex H ...

  5. 2018 icpc 徐州

    A 矩阵树定理可以用于最小生成树计数,最直观的做法就是求个mst,再用矩阵树定理求最小生成树个数,但是n<=1e5,显然不是o(n^3)可以做出来的. 考虑随机数据生成器,固定1e5的边,但是边 ...

  6. 【2018 ICPC亚洲区域赛徐州站 A】Rikka with Minimum Spanning Trees(求最小生成树个数与总权值的乘积)

    Hello everyone! I am your old friend Rikka. Welcome to Xuzhou. This is the first problem, which is a ...

  7. hihoCoder #1871 : Heshen's Account Book-字符串暴力模拟 自闭(getline()函数) (ACM-ICPC Asia Beijing Regional Contest 2018 Reproduction B) 2018 ICPC 北京区域赛现场赛B

    P2 : Heshen's Account Book Time Limit:1000ms Case Time Limit:1000ms Memory Limit:512MB Description H ...

  8. hihoCoder #1870 : Jin Yong’s Wukong Ranking List-闭包传递(递归) (ACM-ICPC Asia Beijing Regional Contest 2018 Reproduction A) 2018 ICPC 北京区域赛现场赛A

    P1 : Jin Yong’s Wukong Ranking List Time Limit:1000ms Case Time Limit:1000ms Memory Limit:512MB Desc ...

  9. 2018徐州现场赛A

    题目链接:http://codeforces.com/gym/102012/problem/A 题目给出的算法跑出的数据是真的水 #include<iostream> #include&l ...

随机推荐

  1. ZooKeeper食谱(八)

    使用ZooKeeper构造高级别应用的指南 在这个文章中,你将会发现使用ZooKeeper来实现高级别功能的指南.所有的它们在客户端上被实现而不需要ZooKeeper特别的支持.希望社区将注意到这些约 ...

  2. LightOJ 1375 - LCM Extreme 莫比乌斯反演或欧拉扩展

    题意:给出n [1,3*1e6] 求 并模2^64. 思路:先手写出算式 观察发现可以化成 那么关键在于如何求得i为1~n的lcm(i,n)之和.可以知道lcm(a,b)为ab/gcd(a,b) 变换 ...

  3. 【LibreOJ】#539. 「LibreOJ NOIP Round #1」旅游路线

    [题意]给定正边权有向图,车油量上限C,每个点可以花费pi加油至min(C,ci),走一条边油-1,T次询问s点出发带钱q,旅行路程至少为d的最多剩余钱数. n<=100,m<=1000, ...

  4. bzoj 2165 DP

    首先如果不考虑数据范围的话,因为每一层都是等效的,所以我们可以用w[i][j][k]来表示在某一层的j位置,称作i次电梯到k位置,最多上升多少层,那么我们可以比较容易的写出转移,因为m十分大,i可能与 ...

  5. Linux中source命令的用法

    source命令: source命令也称为“点命令”,也就是一个点符号(.).source命令通常用于重新执行刚修改的初始化文件,使之立即生效,而不必注销并重新登录.因为linux所有的操作都会变成文 ...

  6. Android控件——Button与ImageButton

    1.简单介绍

  7. Perl6 Bailador框架(1):开始

    use v6; use Bailador; get '/' => sub { '<h1><center>Hello, World</center></h ...

  8. 源码分析之tinyhttpd-0.1

    1. 简介: tinyhttpd是使用c语言开发的超轻量级http服务器,通过代码流程可以了解http服务器的基本处理流程, 并且涉及了网络套接字,线程,父子进程,管道等等知识点: 项目地址:http ...

  9. 2017多校第5场 HDU 6085 Rikka with Candies bitset

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6085 题意:存在两个长度为n,m的数组A,B.有q个询问,每个询问有一个数字k,可以得到Ai%Bj=k ...

  10. centos创建子用户

    #adduser 用户名 #passwd 用户名 设置自己的密码即可 授权 个人用户的权限只可以在本home下有完整权限,其他目录要看别人授权.而经常需要root用户的权限,这时候sudo可以化身为r ...