More than 2019 cattle off summer school camp (ninth field) E All men are brothers

This question is when the game think the correct solution, but still did not dare to do, for fear of a timeout, in fact, that after the way simple disjoint-set + combination of computing.

 

answer:

  1. First is the relationship of the transfer to be considered, which explains who we can not know, is divided into pools.

  2. The rest is a collection of the merger, because we need to calculate the number of combinations, so it is necessary to look at the number collection also recorded.

  3. It is necessary to estimate an explanation of  ans - = a * b * ( pre - a * (n - a) - b * (n - b) + a * b); recommended look at the code

   The current value in the case ans value of a and b are not incorporated, but now a and b have been merged, then we need to subtract the number of a and b contributed combinations

   So a and b contribute to the number of combinations is: Take 1 from a man, and then take one person from b, and then pick 2 people from the rest of the collection

   Code is the a * b * (the number of the remaining set of two picked combination)

   He said pre code is "take two different people borrowing"

   Then the remaining two numbers picked collection is a combination of: pre - A * (n-- A) - B * (n-- B) + A * B 

   Why do you want to add a * b, because (na) is included in the b, (nb) is included in a, in fact, we subtract twice a * b, it is necessary to add back again.

 

  

#include <bits/stdc++.h>

using namespace std;
typedef double dou;
typedef  long long ll;
typedef pair<int, int> pii;
typedef map<int, int> mii;

#define pai acos(-1.0)
#define M 100005
#define inf 0x3f3f3f3f
#define mod 1000000007
#define IN inline
#define left k<<1
#define right k<<1|1
#define lson L, mid, left
#define rson mid + 1, R, right
#define W(a) while(a)
#define lowbit(a) a&(-a)
#define ms(a,b) memset(a,b,sizeof(a))
#define Abs(a) (a ^ (a >> 31)) - (a >> 31)
#define false_stdio ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)

ll n, m;
ll ans, pre, a, b, fa, fb;
ll boss[M], num[M];

int find(int k) {
    if (boss[k] == k)return k;
    else {
        boss[k] = find(boss[k]);
        return boss[k];
    }
}

intmain () { 
    false_stdio; 
    CIN >> n >> m; 
    pre = n * (n - . 1 ) / 2 ; // this is to take two different human individuals in the n-emulated 
    ANS = n / 2 * (n - . 1 ) / . 3 * (n-- 2 ) / . 4 * (n-- . 3 ); // initial maximum value of C (. 4) (n-) 

    for ( int I = . 1 ; I <= n-; I ++ ) {
         / / beginning are not aware of their own so that each set is, only the number. 1 
        NUM [I] = . 1 ; 
        BOSS [I] = I; 
    }
    for ( int I = . 1 ; I <= m; I ++ ) { 
        COUT << ANS << endl; 
        CIN >> A >> B; 
        FA = Find (A), FB = Find (B); // Find the root 
        IF (ANS || FB FA == == 0 ) Continue ; // If the same root, which is a collection, or the answer can not be reduced to 0, then do not calculate 

        a = NUM [FA], B NUM = [fb]; // number of a set where fa, b where fb is the number set
         // read following this explanation may go back to see the 3 
        ans - = a * b * ( pre - a * (n-- A) - B * (n-- B) + A * B); 
        pre - = A * B; //Subtracting the number of combinations of a and b 

        BOSS [FB] = FA; 
        NUM [FA] + = NUM [FB]; 
    } 
    COUT << ANS << endl;
     return  0 ; 
}

 

   

  

Guess you like

Origin www.cnblogs.com/caibingxu/p/11366348.html