Guest User

Untitled

a guest
May 22nd, 2018
80
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.37 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3. #include <algorithm>
  4. #include <set>
  5. using namespace std;
  6.  
  7. long long n,m;
  8. vector <vector <int> > G;
  9. vector <pair<int,int> > M;
  10.  
  11. int dsu_parent[5000];
  12. int dsu_rank[5000];
  13. int size_of_component[5000];
  14. int edges_of_component[5000];
  15. set <int> all_components;
  16. long long C[5001][5001];
  17. long long answer_one=0,answer_two=0,answer_three=0,answer_four=0;
  18. long long real_answer=0;
  19. int MAXN=5000;
  20.  
  21. int dsu_make(int i){
  22.     dsu_parent[i]=i;
  23.     dsu_rank[i]=0;
  24. }
  25.  
  26. void pascal_init(){
  27.     for (int i = 0; i <= MAXN; i++) {
  28.         C[i][0] = C[i][i] = 1;
  29.         for (int k = 1; k < 10; k++)
  30.             C[i][k] = C[i-1][k-1] + C[i-1][k];
  31.     }
  32.     real_answer=C[n][1]+C[n][2]+C[n][3]+C[n][4];
  33. }
  34.  
  35. int dsu_find(int i){
  36.     if (i==dsu_parent[i])
  37.         return i;
  38.     return dsu_parent[i]=dsu_find(dsu_parent[i]);
  39. }
  40.  
  41. void dsu_unite(int a, int b){
  42.     a=dsu_find(a);
  43.     b=dsu_find(b);
  44.     if (a!=b){
  45.         if (dsu_rank[a]<dsu_rank[b])
  46.             swap(a,b);
  47.         dsu_parent[b]=a;
  48.         size_of_component[a]+=size_of_component[b];
  49.         edges_of_component[a]+=edges_of_component[b];
  50.         all_components.erase(b);
  51.         if (dsu_rank[a]==dsu_rank[b])
  52.             dsu_rank[a]++;
  53.     }
  54. }
  55.  
  56. void iterat_for_three(int numb){
  57.     int u=M[numb].first; int v=M[numb].second;
  58.     long long k1=G[u].size();
  59.     long long k2=G[v].size();
  60.     sort (G[u].begin(),G[u].end());
  61.     sort (G[v].begin(),G[v].end());
  62.     vector <int> intersect_of_lists;
  63.     vector<int>::iterator it=set_intersection(G[u].begin(),G[u].end(),G[v].begin(),G[v].end(),intersect_of_lists.begin());
  64.     long long e=it-intersect_of_lists.begin();
  65.     long long answer=(n-2)-k1-k2+e;
  66.     answer_three+=answer;
  67. }
  68.  
  69. void iterat_for_four(int numb){
  70.     //cout<<"ENTER:"<<endl;
  71.     int u=M[numb].first; int v=M[numb].second;
  72.     int u_comp=dsu_find(u); int v_comp=dsu_find(v);
  73.     long long k1=G[u].size();
  74.     long long k2=G[v].size();
  75.     long long answer=0;
  76.     long long k=all_components.size();
  77.     long long sums[5000];
  78.     long long local_sizes[5000];
  79.     for (int j=0;j<5000;j++)
  80.         sums[j]=0,local_sizes[j]=0;
  81.     int i=0;
  82.     for (set<int>::iterator it=all_components.begin();it!=all_components.end();it++,i++){
  83.         int cur_comp=*it;
  84.         if (i) sums[i]+=sums[i-1];
  85.         if (cur_comp!=u_comp && cur_comp!=v_comp){
  86.             sums[i]+=size_of_component[cur_comp];
  87.             local_sizes[i]=size_of_component[cur_comp];
  88.             int socp=size_of_component[cur_comp];
  89.             answer+=(socp*(socp-1))/2-edges_of_component[cur_comp];
  90.         }
  91.     }
  92.     //cout<<"POINT1:"<<answer<<endl;
  93.     for (int i=0;i<k;i++){
  94.         long long chast_sum=sums[k-1];
  95.         chast_sum-=sums[i];
  96.         //cout<<local_sizes[i]<<" ";
  97.         answer+=local_sizes[i]*chast_sum;
  98.     }
  99.     //cout<<"POINT2:"<<answer<<endl;
  100.     if (u_comp!=v_comp){
  101.         long long dob=0;
  102.         long long socp=size_of_component[u_comp];
  103.         dob+=(socp*(socp-1))/2-edges_of_component[u_comp];
  104.         dob-=size_of_component[u_comp]-1-G[u].size();
  105.         socp=size_of_component[v_comp];
  106.         dob+=(socp*(socp-1))/2-edges_of_component[v_comp];
  107.         dob-=size_of_component[v_comp]-1-G[v].size();
  108.         answer+=dob;
  109.         //cout<<"POINT2.5:"<<answer<<endl;
  110.         answer+=(size_of_component[u_comp]-1-G[u].size())*(size_of_component[v_comp]-1-G[v].size());
  111.         for (int i=0;i<k;i++){
  112.             //cout<<"i:"<<i<<" "<<local_sizes[i]<<" "<<size_of_component[u_comp]<<endl;
  113.             answer+=(size_of_component[u_comp]-1-G[u].size())*local_sizes[i];
  114.         }
  115.         //cout<<"POINT2.7:"<<answer<<endl;
  116.         for (int i=0;i<k;i++){
  117.             answer+=(size_of_component[v_comp]-1-G[v].size())*local_sizes[i];
  118.         }
  119.         //cout<<"POINT3:"<<answer<<endl;
  120.     }
  121.     else{
  122.         long long dob=0;
  123.         long long socp=size_of_component[u_comp];
  124.         dob+=(socp*(socp-1))/2-edges_of_component[u_comp];
  125.         dob-=size_of_component[u_comp]-1-G[u].size();
  126.         dob-=size_of_component[v_comp]-1-G[v].size();
  127.         answer+=dob;
  128.         for (int i=0;i<k;i++){
  129.             answer+=(size_of_component[u_comp]-2)*local_sizes[i];
  130.         }
  131.     }
  132.     answer_four+=answer;
  133.     G[u].push_back(u);
  134.     G[v].push_back(v);
  135.     dsu_unite(u,v);
  136.     u_comp=dsu_find(u);
  137.     edges_of_component[u_comp]++;
  138.     //cout<<"EXIT"<<endl;
  139. }
  140.  
  141. int main(){
  142.     cin>>n>>m;
  143.     G.resize(n);
  144.     M.resize(m);
  145.     answer_one=0; answer_two=m;
  146.     for (int i=0;i<m;i++){
  147.         int a,b; cin>>a>>b;
  148.         a--; b--;
  149.         if (a>b) swap(a,b);
  150.         M[i]=(make_pair(a,b));
  151.     }
  152.     for (int i=0;i<n;i++){
  153.         dsu_make(i);
  154.         size_of_component[i]=1;
  155.         all_components.insert(i);
  156.     }
  157.     for (int i=0;i<m;i++){
  158.         iterat_for_three(i);
  159.         iterat_for_four(i);
  160.     }
  161.     pascal_init();
  162.     //cout<<answer_four<<endl;
  163.     cout<<real_answer-answer_one-answer_two-answer_three-answer_four<<endl;
  164.     return 0;
  165. }
Add Comment
Please, Sign In to add comment