#include <iostream>
#include <vector>
#include <math.h>
using namespace std;
struct Range{
int min, max;
Range(int min, int max): min(min), max(max){}
static Range * commonPart(const Range * r1, const Range * r2){
int min = r1->min > r2->min ? r1->min : r2->min;
int max = r1->max < r2->max ? r1->max : r2->max;
return new Range(min, max);
}
};
struct SegmentTree{
struct BinaryNode{
const int id;
Range * range;
bool colours[3] = {false};//yellow, blue, red
BinaryNode(int id) : id(id){};
~BinaryNode(){
delete range;
}
};
vector<BinaryNode *> nodes;
int height;
int firstFloorSize;
SegmentTree(int dataLength){
float logVal = log2(dataLength);
this->height = (int)logVal + (((int)logVal) != logVal) + 1;
this->firstFloorSize = pow(2, height - 1);
int totalNodes = pow(2, height) - 1;
for(int i = 0; i < totalNodes; i ++){
nodes.push_back(new BinaryNode(i));
}
for(int i = 0; i < firstFloorSize; i ++){
int nodeID = nodes.size() - 1 - i;
nodes[nodeID]->range = new Range(firstFloorSize - 1 - i, firstFloorSize - 1 - i);
}
for(int i = 0; i < nodes.size() - firstFloorSize; i ++){
int nodeID = nodes.size() - firstFloorSize - 1 - i;
BinaryNode * leftChild = nodes[getChildID(nodeID, true)];
BinaryNode * rightChild = nodes[getChildID(nodeID, false)];
nodes[nodeID]->range = new Range(leftChild->range->min, rightChild->range->max);
}
cout<<"";
}
static int getChildID(int parentID, bool left){
return parentID * 2 + 1 + !left;
}
static int getParentID(int childID){
return (childID - 1) / 2;
}
void propagate(Range * range, int colour, int nodeID = 0){
BinaryNode * node = nodes[nodeID];
if(node->range->min == range->min && node->range->max == range->max){
node->colours[colour] = true;
}
else if(getChildID(nodeID, false) < nodes.size() && range->min <= range->max){
int leftID = getChildID(nodeID, true);
int rightID = getChildID(nodeID, false);
Range * commonLeft = Range::commonPart(range, nodes[leftID]->range);
Range * commonRight = Range::commonPart(range, nodes[rightID]->range);
propagate(commonLeft, colour, leftID);
propagate(commonRight, colour, rightID);
delete commonLeft;
delete commonRight;
}
}
bool isGreen(int leafID){
int nodeID = nodes.size() - firstFloorSize + leafID;
BinaryNode * node = nodes[nodeID];
bool colours[3] = {false};
while(true){
for(int i = 0; i < 3; i ++){
colours[i] += node->colours[i];
}
if(getParentID(node->id) == node->id)
break;
node = nodes[getParentID(node->id)];
}
return colours[0] && colours[1] && !colours[2];
}
~SegmentTree(){
for(auto n : nodes){
delete n;
}
}
};
int main() {
std::ios_base::sync_with_stdio(false);
int length;
int queries;
cin >> length;
cin >> queries;
SegmentTree sg = SegmentTree(length);
for(int i = 0; i < queries; i ++){
int min, max, colour;
cin >> min;
cin >> max;
cin >> colour;
Range * r = new Range(--min, --max);
sg.propagate(r, --colour);
delete r;
}
int sum = 0;
for(int i = 0; i < length; i ++){
sum += sg.isGreen(i);
}
cout<<sum;
return 0;
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 | #include <iostream> #include <vector> #include <math.h> using namespace std; struct Range{ int min, max; Range(int min, int max): min(min), max(max){} static Range * commonPart(const Range * r1, const Range * r2){ int min = r1->min > r2->min ? r1->min : r2->min; int max = r1->max < r2->max ? r1->max : r2->max; return new Range(min, max); } }; struct SegmentTree{ struct BinaryNode{ const int id; Range * range; bool colours[3] = {false};//yellow, blue, red BinaryNode(int id) : id(id){}; ~BinaryNode(){ delete range; } }; vector<BinaryNode *> nodes; int height; int firstFloorSize; SegmentTree(int dataLength){ float logVal = log2(dataLength); this->height = (int)logVal + (((int)logVal) != logVal) + 1; this->firstFloorSize = pow(2, height - 1); int totalNodes = pow(2, height) - 1; for(int i = 0; i < totalNodes; i ++){ nodes.push_back(new BinaryNode(i)); } for(int i = 0; i < firstFloorSize; i ++){ int nodeID = nodes.size() - 1 - i; nodes[nodeID]->range = new Range(firstFloorSize - 1 - i, firstFloorSize - 1 - i); } for(int i = 0; i < nodes.size() - firstFloorSize; i ++){ int nodeID = nodes.size() - firstFloorSize - 1 - i; BinaryNode * leftChild = nodes[getChildID(nodeID, true)]; BinaryNode * rightChild = nodes[getChildID(nodeID, false)]; nodes[nodeID]->range = new Range(leftChild->range->min, rightChild->range->max); } cout<<""; } static int getChildID(int parentID, bool left){ return parentID * 2 + 1 + !left; } static int getParentID(int childID){ return (childID - 1) / 2; } void propagate(Range * range, int colour, int nodeID = 0){ BinaryNode * node = nodes[nodeID]; if(node->range->min == range->min && node->range->max == range->max){ node->colours[colour] = true; } else if(getChildID(nodeID, false) < nodes.size() && range->min <= range->max){ int leftID = getChildID(nodeID, true); int rightID = getChildID(nodeID, false); Range * commonLeft = Range::commonPart(range, nodes[leftID]->range); Range * commonRight = Range::commonPart(range, nodes[rightID]->range); propagate(commonLeft, colour, leftID); propagate(commonRight, colour, rightID); delete commonLeft; delete commonRight; } } bool isGreen(int leafID){ int nodeID = nodes.size() - firstFloorSize + leafID; BinaryNode * node = nodes[nodeID]; bool colours[3] = {false}; while(true){ for(int i = 0; i < 3; i ++){ colours[i] += node->colours[i]; } if(getParentID(node->id) == node->id) break; node = nodes[getParentID(node->id)]; } return colours[0] && colours[1] && !colours[2]; } ~SegmentTree(){ for(auto n : nodes){ delete n; } } }; int main() { std::ios_base::sync_with_stdio(false); int length; int queries; cin >> length; cin >> queries; SegmentTree sg = SegmentTree(length); for(int i = 0; i < queries; i ++){ int min, max, colour; cin >> min; cin >> max; cin >> colour; Range * r = new Range(--min, --max); sg.propagate(r, --colour); delete r; } int sum = 0; for(int i = 0; i < length; i ++){ sum += sg.isGreen(i); } cout<<sum; return 0; } |
English