C ++
 Computer >> コンピューター >  >> プログラミング >> C ++

C ++でBITを使用して、色付きツリーのサブツリー内の個別の色の数をクエリする


このチュートリアルでは、BITを使用して色付きツリーのサブツリー内の異なる色の数を照会するプログラムについて説明します。

このために、各ノードが指定された配列で示される色を持つルートツリーが提供されます。私たちのタスクは、ツリー内の特定のノードの下にあるすべての異なる色のノードを見つけることです。

#include<bits/stdc++.h>
#define MAXIMUM_COLOUR 1000005
#define MAXIMUM_NUMBER 100005
using namespace std;
vector<int> tree[MAXIMUM_NUMBER];
vector<int> table[MAXIMUM_COLOUR];
int isTraversing[MAXIMUM_COLOUR];
int bit[MAXIMUM_NUMBER], getVisTime[MAXIMUM_NUMBER],
getEndTime[MAXIMUM_NUMBER];
int getFlatTree[2 * MAXIMUM_NUMBER];
bool vis[MAXIMUM_NUMBER];
int tim = 0;
vector< pair< pair<int, int>, int> > queries;
//storing results of each queryingTree
int ans[MAXIMUM_NUMBER];
void update(int idx, int val) {
   while ( idx < MAXIMUM_NUMBER ) {
      bit[idx] += val;
      idx += idx & -idx;
   }
}
int queryingTree(int idx) {
   int result = 0;
   while ( idx > 0 ) {
      result += bit[idx];
      idx -= idx & -idx;
   }
   return result;
}
void preformingDFS(int v, int color[]) {
   //marking the node visited
   vis[v] = 1;
   getVisTime[v] = ++tim;
   getFlatTree[tim] = color[v];
   vector<int>::iterator it;
   for (it=tree[v].begin(); it!=tree[v].end(); it++)
      if (!vis[*it])
         preformingDFS(*it, color);
   getEndTime[v] = ++tim;
   getFlatTree[tim] = color[v];
}
//adding an edge to the tree
void addingNewEdge(int u, int v) {
   tree[u].push_back(v);
   tree[v].push_back(u);
}
void markingFirstFind(int n) {
   for (int i = 1 ; i <= 2 * n ; i++) {
      table[getFlatTree[i]].push_back(i);
      if (table[getFlatTree[i]].size() == 1) {
         update(i, 1);
         isTraversing[getFlatTree[i]]++;
      }
   }
}
void calcQuery() {
   int j = 1;
   for (int i=0; i<queries.size(); i++) {
      for ( ; j < queries[i].first.first ; j++ ) {
         int elem = getFlatTree[j];
         update( table[elem][isTraversing[elem] - 1], -1);
         if ( isTraversing[elem] < table[elem].size() ){
            update(table[elem][ isTraversing[elem] ], 1);
            isTraversing[elem]++;
         }
      }
      ans[queries[i].second] = queryingTree(queries[i].first.second);
   }
}
//counting distinct color nodes
void calcAllColours(int color[], int n, int qVer[], int qn) {
   preformingDFS(1, color);
   for (int i=0; i<qn; i++)
      queries.push_back(make_pair(make_pair(getVisTime[qVer[i]] , getEndTime[qVer[i]]), i) );
   sort(queries.begin(), queries.end());
   markingFirstFind(n);
   calcQuery();
   for (int i=0; i<queries.size() ; i++) {
      cout << "All distinct colours in the given tree: " << ans[i] << endl;
   }
}
int main() {
   int number = 6;
   int color[] = {0, 2, 3, 3, 4, 1};
   addingNewEdge(1, 2);
   addingNewEdge(1, 3);
   addingNewEdge(2, 4);
   int queryVertices[] = {3, 2};
   int qn = sizeof(queryVertices)/sizeof(queryVertices[0]);
   calcAllColours(color, number, queryVertices, qn);
   return 0;
}

出力

All distinct colours in the given tree: 1
All distinct colours in the given tree: 2

  1. C++を使用して文字列の部分文字列の数を見つける

    この記事では、特定の文字列に形成できるサブ文字列(空ではない)の数を見つけるためのアプローチについて学習します。 Input : string = “moon” Output : 10 Explanation: Substrings are ‘m’, ‘o’, ‘o’, ‘n’, ‘mo’, ‘oo’, ‘on’, ‘moo’, ‘oon’ and &

  2. C++を使用してN-aryツリーをトラバースする方法の数を見つける

    N-aryツリーが与えられ、このツリーをトラバースする方法の総数を見つける必要があります。たとえば、- 上記のツリーの場合、出力は192になります。 この問題については、組み合わせ論についての知識が必要です。この問題では、すべてのパスで可能なすべての組み合わせを確認するだけで、答えが得られます。 解決策を見つけるためのアプローチ このアプローチでは、レベル順トラバーサルを実行し、各ノードの子の数を確認してから、階乗を答えに乗算するだけです。 例 上記のアプローチのC++コード #include<bits/stdc++.h> using namespace std;