#include "bits/stdc++.h" using namespace std; class node{ public: int colors[4]; int rangeCount; node():colors{0, 0, 0, 0}{ rangeCount = 0; } void putColorInLeaf(int color){ colors[color]=1; } int calculateGreen(){ return max(0, min(colors[0], colors[1]) - colors[2]); } void setGreen(){ colors[3] = calculateGreen(); } void removeRed(){ colors[2] = 0; } void setGreen(node* left, node* right){ bool adding = 1; for(int i=0; i<3; i++){ if(left->colors[i] + right->colors[i] != colors[i]){ adding = 0; break; } } if(!adding){ setGreen(); } else{ colors[3] = left->colors[3] + right->colors[3]; } int test=0; } int getColorCount(int color){ return colors[color]; } void sumColorCount(int color, int leftV, int rightV){ colors[color]=max(colors[color], leftV+rightV); } }; namespace tree{ #define M 1048576 node array[2*M]; int treeSize, size; int getFirstNotSmallerPowerOfTwo(int n){ int result = 1; while(n > result){ result *= 2; } return result; } void init(int n){ size = n; treeSize = getFirstNotSmallerPowerOfTwo(n); for(int i=0; i<size; i++){ array[i+treeSize].rangeCount = 1; } for(int i=size; i<treeSize; i++){ array[i+treeSize].rangeCount = 0; } int depth = 2; while(treeSize/depth){ for(int i=0; i<treeSize/depth; i++){ array[i+treeSize/depth].rangeCount = array[(i+treeSize/depth)*2].rangeCount + array[(i+treeSize/depth)*2+1].rangeCount; } depth *= 2; } } int calculateGreen(){ for(int i=0; i<size; i++){ array[i+treeSize].setGreen(); } int depth = 2; while(treeSize/depth){ for(int i=0; i<treeSize/depth; i++){ node* first = &array[(i+treeSize/depth)*2], *second = &array[(i+treeSize/depth)*2+1]; array[i+treeSize/depth].setGreen(first, second); } depth *= 2; } return array[1].getColorCount(3); } void insert(int a, int b, int val){ int left = treeSize + a, right = treeSize + b; array[left].putColorInLeaf(val); array[right].putColorInLeaf(val); while(left/2){ if(left/2 == right/2 && left != right){ // schodza sie sciezki array[left/2].sumColorCount(val, array[left].getColorCount(val), array[right].getColorCount(val)); } else if(left/2 == right/2 && left == right){ //juz sie zeszly if(left % 2 == 0){ array[left/2].sumColorCount(val, array[left].getColorCount(val), array[left+1].getColorCount(val)); } else { array[left/2].sumColorCount(val, array[left].getColorCount(val), array[left-1].getColorCount(val)); } } else if(left/2 != right/2){ if(left % 2 == 0){ array[left/2].sumColorCount(val, array[left].getColorCount(val), array[left+1].rangeCount); array[left+1].colors[val] = array[left+1].rangeCount; } else { array[left/2].sumColorCount(val, array[left].getColorCount(val), array[left-1].getColorCount(val)); } if(right % 2 == 1){ array[right/2].sumColorCount(val, array[right].getColorCount(val), array[right-1].rangeCount); array[right-1].colors[val] = array[right-1].rangeCount; } else { array[right/2].sumColorCount(val, array[right].getColorCount(val), array[right+1].getColorCount(val)); } } left /= 2; right /= 2; } } } int main(){ int n,m; cin >> n >> m; tree::init(n); while(m--){ int l, r, k; cin >> l >> r >> k; tree::insert(l-1, r-1, k-1); } int debug = 0; cout << tree::calculateGreen(); debug = 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 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 | #include "bits/stdc++.h" using namespace std; class node{ public: int colors[4]; int rangeCount; node():colors{0, 0, 0, 0}{ rangeCount = 0; } void putColorInLeaf(int color){ colors[color]=1; } int calculateGreen(){ return max(0, min(colors[0], colors[1]) - colors[2]); } void setGreen(){ colors[3] = calculateGreen(); } void removeRed(){ colors[2] = 0; } void setGreen(node* left, node* right){ bool adding = 1; for(int i=0; i<3; i++){ if(left->colors[i] + right->colors[i] != colors[i]){ adding = 0; break; } } if(!adding){ setGreen(); } else{ colors[3] = left->colors[3] + right->colors[3]; } int test=0; } int getColorCount(int color){ return colors[color]; } void sumColorCount(int color, int leftV, int rightV){ colors[color]=max(colors[color], leftV+rightV); } }; namespace tree{ #define M 1048576 node array[2*M]; int treeSize, size; int getFirstNotSmallerPowerOfTwo(int n){ int result = 1; while(n > result){ result *= 2; } return result; } void init(int n){ size = n; treeSize = getFirstNotSmallerPowerOfTwo(n); for(int i=0; i<size; i++){ array[i+treeSize].rangeCount = 1; } for(int i=size; i<treeSize; i++){ array[i+treeSize].rangeCount = 0; } int depth = 2; while(treeSize/depth){ for(int i=0; i<treeSize/depth; i++){ array[i+treeSize/depth].rangeCount = array[(i+treeSize/depth)*2].rangeCount + array[(i+treeSize/depth)*2+1].rangeCount; } depth *= 2; } } int calculateGreen(){ for(int i=0; i<size; i++){ array[i+treeSize].setGreen(); } int depth = 2; while(treeSize/depth){ for(int i=0; i<treeSize/depth; i++){ node* first = &array[(i+treeSize/depth)*2], *second = &array[(i+treeSize/depth)*2+1]; array[i+treeSize/depth].setGreen(first, second); } depth *= 2; } return array[1].getColorCount(3); } void insert(int a, int b, int val){ int left = treeSize + a, right = treeSize + b; array[left].putColorInLeaf(val); array[right].putColorInLeaf(val); while(left/2){ if(left/2 == right/2 && left != right){ // schodza sie sciezki array[left/2].sumColorCount(val, array[left].getColorCount(val), array[right].getColorCount(val)); } else if(left/2 == right/2 && left == right){ //juz sie zeszly if(left % 2 == 0){ array[left/2].sumColorCount(val, array[left].getColorCount(val), array[left+1].getColorCount(val)); } else { array[left/2].sumColorCount(val, array[left].getColorCount(val), array[left-1].getColorCount(val)); } } else if(left/2 != right/2){ if(left % 2 == 0){ array[left/2].sumColorCount(val, array[left].getColorCount(val), array[left+1].rangeCount); array[left+1].colors[val] = array[left+1].rangeCount; } else { array[left/2].sumColorCount(val, array[left].getColorCount(val), array[left-1].getColorCount(val)); } if(right % 2 == 1){ array[right/2].sumColorCount(val, array[right].getColorCount(val), array[right-1].rangeCount); array[right-1].colors[val] = array[right-1].rangeCount; } else { array[right/2].sumColorCount(val, array[right].getColorCount(val), array[right+1].getColorCount(val)); } } left /= 2; right /= 2; } } } int main(){ int n,m; cin >> n >> m; tree::init(n); while(m--){ int l, r, k; cin >> l >> r >> k; tree::insert(l-1, r-1, k-1); } int debug = 0; cout << tree::calculateGreen(); debug = 0; } |