E - Little W and Contest

https://vjudge.net/contest/386223#problem/E

 

There are  nn members in our ACM club. Little W wants to select three persons from our club to form a new team taking part in provincial ACM contests, as it is known by all of us that any ACM contest requires a normal team to have three members.
Little W has divided our club members into two role groups. The first group contains only readers who dedicate themselves to reading problems during contests, though sometimes they may also prepare drinking and food for the team. For the sake of measurement, we define the power of a reader as 11. The second part contains only coders who code and test programs all the time, and similarly, we define the power of a coder as 22.
Little W thinks it will be a tremendous disaster when a team has two readers because in that case, the total power of this team is less than 55 and thus it has a high risk to fail the contest. To avoid that, Little W thinks a new team must have at least two coders.
Additionally, Little W defines the relationship between club members with transitivity. That is, for every three members AA, BB, and CC, if AA is familiar with BB, and BB is familiar with CC, then AA will be familiar with CC through BB instantly. Based on the definition, it is forbidden for the team to have any two members familiar with each other.
At first, no member of our club is familiar with any other, and then Little W will repeatedly make an introduction between two members who are currently strangers to each other until each member is familiar with all the others. During this process, there will be exactly (n1)(n−1) introductions.
Now, for i=1,2,,ni=1,2,…,n, Little W wants you to count the combinations of three club members that can form a new team after the first (i1)(i−1) introductions have been made. However, the numbers of combinations may be quite gigantic, so you just need to report each number in modulo (109+7)(109+7).

InputThere are several test cases.
The first line contains an integer TT (1T101≤T≤10), denoting the number of test cases. Then follow all the test cases.
For each test case, the first line contains an integer n(1n105)(1≤n≤105), denoting the number of members in this club.
The second line contains nn integers consisting of only 11 and 22, where the ii-th integer represents the power of the ii-th member.
The next (n1)(n−1) lines describe all introductions in chronological order of occurrence, where each line contains two integers uu and v(1u,vn,uv)(1≤u,v≤n,u≠v), representing an introduction between the uu-th member and the vv-th member, who are currently strangers to each other.
It is guaranteed that the sum of nn is no larger than 106106.
OutputFor each test case, output nn lines, where the ii-th line contains an integer, denoting the number of combinations of three club members, in modulo (109+7)(109+7), that can form a new team after the first (i1)(i−1) introductions have been made.
Sample Input

1
5
2 2 2 1 1
4 5
1 4
2 1
3 2

Sample Output

7
7
3
0
0

Sponsor

题意:

  n个人互不认识,经过一次介绍,两人认识,认识关系具有传递性,n-1次介绍后两联认识;

  每个人都具有属性1或2,从n个人中选择三个人参加比赛,且至少有两个具有属性2,且三个人互不认识。

  问每给一次介绍后有多少种凑出来一个队的组合

思路;

利用并查集,将所有的点分成三个部分(三种连通块),每次去不同块中取不满足的情况,

求出总的方案数

merge先计算贡献。合并集合产生四种情况

去合并的负贡献:每次用前一次的减去不满足的情况个数,得到结果。

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<bitset>
#include<cassert>
#include<cctype>
#include<cmath>
#include<cstdlib>
#include<ctime>
#include<deque>
#include<iomanip>
#include<list>
#include<map>
#include<queue>
#include<set>
#include<stack>
#include<vector>
#include <vector>
#include <iterator>
#include <utility>
#include <sstream>
#include <limits>
#include <numeric>
#include <functional>
using namespace std;
#define gc getchar()
#define mem(a) memset(a,0,sizeof(a))
//#define sort(a,n,int) sort(a,a+n,less<int>())

#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);

typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int,int> pii;
typedef char ch;
typedef double db;

const double PI=acos(-1.0);
const double eps=1e-6;
const int inf=0x3f3f3f3f;
const int maxn=1e5+10;
const int maxm=100+10;
const int N=2e5+10;
const int mod=1e9+7;
ll n = 0;
ll p[100005] = {0};
ll p1[100005] = {0};
ll p2[100005] = {0};
ll In, K;
ll temp;
ll ans;
ll x, y, k = 0;
ll inv(ll a)
{
    return a == 1 ? 1 : (ll)(mod-mod/a)*inv(mod%a)%mod;
}
ll comb(ll n,ll m)
{
    if(m < 0)return 0;
    if(n < m)return 0;
    if(m > n-m) m = n-m;
    ll up = 1;
	ll down = 1;
    for(ll i = 0;i<m;i++)
    {
        up = up * (n-i) % mod;
        down = down * (i+1) % mod;
    }
    return up*inv(down) %mod;
}
ll find(ll x)
{
	if(x != p[x])
		return p[x] = find(p[x]);
	return x;
}

void merge(ll x, ll y)
{
	x = find(x);
	y = find(y);
	p1[y] += p1[x];
	p2[y] += p2[x];
	p[x] = y;
}
int main()
{
	int T = 0;
	cin >> T;
	while(T--)
	{
		cin >> n;
		In = 0; 
		K = 0;
		for(ll i = 1;i<=n;i++) 
		{
			p[i] = i;
			cin >> temp;
			if(temp == 1)
			{
			 	In += 1;
				p1[i] = 1; 
				p2[i] = 0;
			}
			else
			{
				K += 1;
				p1[i] = 0;
				p2[i] = 1;
			}
		}
		ans = (In*comb(K, 2)%mod + comb(K, 3))%mod;
		
		cout << ans <<endl;
		for(int i = 1;i<=n-1;i++)
		{
			k = 0;
			cin >> x >> y;
			x = find(x);
			y = find(y);
			k = (k + p2[x]*p2[y] * (In- p1[x]- p1[y]))%mod;
			k = (k + p2[x]*p2[y] * (In- p2[x]- p2[y]))%mod;
			k = (k + p1[x]*p2[y] * (In- p2[x]- p2[y]))%mod;
			k = (k + p2[x]*p1[y] * (In- p2[x]- p2[y]))%mod;
			merge(x, y);
			ans += mod - k;
			ans %= mod;
			cout << ans << endl;
		}
	}
}

  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

YukiRinLL

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值