Advertisement
Guest User

Untitled

a guest
Jan 15th, 2012
119
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.92 KB | None | 0 0
  1. #include <iostream>
  2. #include <iomanip>
  3. #include <vector>
  4. #include <map>
  5. #include <string>
  6. #include <cstring>
  7. #include <set>
  8. #include <queue>
  9. #include <stack>
  10. #include <bitset>
  11. #include <algorithm>
  12. #include <cstdio>
  13. #include <cstdlib>
  14. #include <cmath>
  15.  
  16. using namespace std;
  17.  
  18. #define MAXN 5010
  19. #define ap(a1, an, n) (((a1) + (an)) * (n) / 2)
  20.  
  21. long long C [MAXN + 10][15];
  22.  
  23. long long n, m, vh[5000], ans;
  24. vector < vector <long long> > g;
  25.  
  26. long long dsu_parent[MAXN + 10], dsu_rank[MAXN + 10], dsu_vert[MAXN + 10], dsu_edge[MAXN + 10];
  27. set <long long> all_cmp;
  28.  
  29. void make_set (long long v)
  30. {
  31.     dsu_parent[v] = v;
  32.     dsu_rank[v] = 0;
  33. }
  34.  
  35. long long find_set (long long v)
  36. {
  37.     if (v == dsu_parent[v])
  38.         return v;
  39.  
  40.     return dsu_parent[v] = find_set (dsu_parent[v]);
  41. }
  42.  
  43. long long union_sets (long long a, long long b)
  44. {
  45.     a = find_set (a);
  46.     b = find_set (b);
  47.  
  48.     if (a != b)
  49.     {
  50.         if (dsu_rank[a] < dsu_rank[b])
  51.             swap (a, b);
  52.  
  53.         dsu_parent[b] = a;
  54.         dsu_vert[a] += dsu_vert[b];
  55.         dsu_edge[a] += dsu_edge[b];
  56.         all_cmp.erase(b);
  57.  
  58.         if (dsu_rank[a] == dsu_rank[b])
  59.             dsu_rank[a]++;
  60.     }
  61.    
  62.     return a;
  63. }
  64.  
  65. int main()
  66. {
  67.     freopen("input.txt", "r", stdin);
  68.     freopen("output.txt", "w", stdout);
  69.  
  70.     long long i, ii, j, u, v, mn3, mn4, uc, vc, k, ps[MAXN], ca[MAXN];
  71.     vector <long long> ins;
  72.     vector <long long> :: iterator it, ite, itu;
  73.     set <long long> :: iterator sit;
  74.  
  75.     for (i = 1; i <= MAXN; i++)
  76.     {
  77.         C[i][0] = C[i][i] = 1;
  78.  
  79.         for (j = 1; j < 10; j++)
  80.             C[i][j] = C[i - 1][j - 1] + C[i - 1][j];
  81.     }
  82.  
  83.     //////////////////// PREPARING OVER /////////////////////
  84.  
  85.     cin >> n >> m;
  86.  
  87.     ans = n + n * (n - 1) / 2 + C[n+1][3] + C[n+1][4];
  88.  
  89.     g.resize(n);
  90.  
  91.     for (i = 0; i < n; i++)
  92.     {
  93.         make_set (i);
  94.         dsu_vert[i] = 1;
  95.         all_cmp.insert(i);
  96.     }
  97.  
  98.     for (ii = 0; ii < m; ii++)
  99.     {
  100.         cin >> u >> v;
  101.         u--, v--;
  102.  
  103.         ans--;
  104.  
  105.         ///////////////////////// 3 /////////////////////////
  106.  
  107.         mn3 = n - 2 - (g[u].size() + g[v].size());
  108.        
  109.         sort(g[u].begin(), g[u].end());
  110.         sort(g[v].begin(), g[v].end());
  111.  
  112.         ins.resize(g[u].size() + g[v].size());
  113.  
  114.         it = set_intersection (g[u].begin(), g[u].end(), g[v].begin(), g[v].end(), ins.begin());
  115.  
  116.         mn3 += long long (it - ins.begin());
  117.  
  118.         ///////////////////////// 4 /////////////////////////
  119.  
  120.         uc = find_set(u); vc = find_set(v);
  121.         for (i = 0; i < MAXN; i++)
  122.             ps[i] = 0, ca[i] = 0;
  123.  
  124.         mn4 = 0;
  125.  
  126.         i = 0;
  127.         for (sit = all_cmp.begin(); sit != all_cmp.end(); sit++, i++)
  128.         {
  129.             if (i)
  130.                 ps[i] += ps[i - 1];
  131.            
  132.             long long cur = *sit;
  133.  
  134.             if (cur != uc && cur != vc)
  135.             {
  136.                 ps[i] += dsu_vert[cur];
  137.                 ca[i] = dsu_vert[cur];
  138.                 mn4 += (dsu_vert[cur] * (dsu_vert[cur] - 1)) / 2 - dsu_edge[cur];
  139.             }
  140.         }
  141.  
  142.         k = all_cmp.size();
  143.  
  144.         for (i = 0; i < k; i++)
  145.         {
  146.             long long cur_part_sum = 0;
  147.            
  148.             cur_part_sum = ps[k - 1];
  149.             cur_part_sum -= ps[i];
  150.             mn4 += ca[i] * cur_part_sum;
  151.         }
  152.  
  153.         if (uc != vc)
  154.         {
  155.             long long soc_u = dsu_vert[uc], soc_v = dsu_vert[vc], eoc_u = dsu_edge[uc], eoc_v = dsu_edge[vc], k1 = g[u].size(), k2 = g[v].size();
  156.             bool B1[MAXN] = {}, B2[MAXN] = {};
  157.  
  158.             long long bad_edges = 0, sum_of_steps = 0, novalid_empty_edges = 0;
  159.  
  160.             B1[u] = true;
  161.  
  162.             sum_of_steps += k1;
  163.             bad_edges += k1;
  164.  
  165.             for (i = 0; i < k1; i++)
  166.             {
  167.                 B1[g[u][i]] = true;
  168.                 sum_of_steps += g[g[u][i]].size();
  169.             }
  170.  
  171.             for (i = 0; i < g[u].size(); i++)  
  172.                 for (j = 0; j < g[g[u][i]].size(); j++)
  173.                     if (B1[g[g[u][i]][j]])
  174.                         bad_edges++;
  175.  
  176.             bad_edges >>= 1;
  177.             sum_of_steps -= bad_edges;
  178.  
  179.             novalid_empty_edges = ap(soc_u - 1, soc_u - 1 - k1, (soc_u - 1) - (soc_u - 1 - k1) + 1) - sum_of_steps;
  180.             mn4 += (soc_u * (soc_u - 1)) / 2 - eoc_u - novalid_empty_edges;
  181.        
  182.             bad_edges = sum_of_steps = 0;
  183.             B2[v] = true;
  184.  
  185.             sum_of_steps += k2;
  186.  
  187.             bad_edges += k2;
  188.  
  189.             for (i = 0; i < g[v].size(); i++)
  190.             {
  191.                 B2[g[v][i]] = true;
  192.                 sum_of_steps += g[g[v][i]].size();
  193.             }
  194.  
  195.             for (i = 0; i < g[v].size(); i++)
  196.                 for (j = 0; j < g[g[v][i]].size(); j++)
  197.                     if (B2[g[g[v][i]][j]])
  198.                         bad_edges++;
  199.  
  200.             bad_edges >>= 1;
  201.             sum_of_steps -= bad_edges;
  202.  
  203.             novalid_empty_edges = ap(soc_v - 1, soc_v - 1 - k2, (soc_v - 1) - (soc_v - 1 - k2) + 1) - sum_of_steps;
  204.  
  205.             mn4 += (soc_v * (soc_v - 1)) / 2 - eoc_v - novalid_empty_edges;
  206.        
  207.             mn4 += (soc_u - 1 - k1) * (soc_v - 1 - k2);
  208.        
  209.             for (i = 0; i < k; i++)
  210.                 mn4 += (soc_u - 1 - k1) * ca[i] + (soc_v - 1 - k2) * ca[i];
  211.         }
  212.         else
  213.         {
  214.             long long soc = dsu_vert[uc], eoc = dsu_edge[vc], k1 = g[u].size(), k2 = g[v].size();
  215.  
  216.             vector <long long> intersect_of_lists(g[u].size() + g[v].size());
  217.             vector <long long> union_of_lists(g[u].size() + g[v].size());
  218.  
  219.             ite = set_intersection(g[u].begin(), g[u].end(), g[v].begin(), g[v].end(), intersect_of_lists.begin());
  220.             itu = set_union(g[u].begin(), g[u].end(), g[v].begin(), g[v].end(), union_of_lists.begin());
  221.            
  222.             long long ke = ite - intersect_of_lists.begin(), ku = itu - union_of_lists.begin();
  223.  
  224.             intersect_of_lists.resize(ke);
  225.             union_of_lists.resize(ku);
  226.        
  227.             bool B[5001] = {};
  228.             long long bad_edges = 0, sum_of_steps =  0, novalid_empty_edges = 0;
  229.  
  230.             B[v] = true;
  231.             B[u] = true;
  232.  
  233.             sum_of_steps += k1 + k2;
  234.             bad_edges += k1 + k2;
  235.  
  236.             for (i = 0; i < ku; i++)
  237.             {
  238.                 B[union_of_lists[i]] = true;
  239.                 sum_of_steps += g[union_of_lists[i]].size();
  240.             }
  241.  
  242.             for (i = 0; i < ku; i++)
  243.                 for (j = 0; j < g[union_of_lists[i]].size(); j++)
  244.                     if (B[g[union_of_lists[i]][j]]) bad_edges++;
  245.  
  246.             bad_edges /= 2;
  247.             sum_of_steps -= bad_edges;
  248.             novalid_empty_edges = ap(soc - 1, soc - 2 - ku, (soc - 1) - (soc - 2 - ku) + 1) - sum_of_steps;
  249.             mn4 += (soc * (soc - 1)) / 2 - eoc - novalid_empty_edges;
  250.        
  251.             for (i = 0; i < k; i++)
  252.                 mn4 += (soc - 2 - ku) * ca[i];
  253.         }
  254.  
  255.         ///////////////////////// M /////////////////////////
  256.  
  257.         ans -= mn3 + mn4;
  258.  
  259.         g[u].push_back(v);
  260.         g[v].push_back(u);
  261.         dsu_edge[union_sets(u, v)]++;      
  262.     }
  263.  
  264.     cout << ans;
  265.  
  266.     return 0;
  267. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement