关于线段树 基本思想是通过平衡二叉树表示线段 // pku2777 Count Color #include <cstdio> #include <cstring> typedef long INT32; typedef unsigned long UINT32; #define MAX_COLOR 30 INT32 alColorShift[MAX_COLOR+1]; #define MAX_L 262144 //#define MAX_L 32 struct NODE { INT32 left; INT32 right; INT32 color; INT32 nextLeft; INT32 nextRight; }; NODE tree[MAX_L+1]; inline void swap(INT32& a, INT32& b) { INT32 tmp = a; a = b; b = tmp; } INT32 buildTree(INT32 index, INT32 left, INT32 right) { if (left > right) return 0; tree[index].left = left; tree[index].right = right; //tree[index].color = 1; if (left < right) { INT32 mid = (left+right) / 2; tree[index].nextLeft = buildTree(index+index, left, mid); tree[index].nextRight = buildTree(index+index+1, mid+1, right); } else //if (left == right) { tree[index].nextLeft = 0; tree[index].nextRight = 0; } return index; } void paint(INT32 left, INT32 right, INT32 color, INT32 index=1) { if (0 == index) return; if (left<=tree[index].left && tree[index].right<=right) tree[index].color = color; else { if (tree[index].color) { tree[ tree[index].nextLeft ].color = tree[index].color; tree[ tree[index].nextRight ].color = tree[index].color; } tree[index].color = 0; INT32 mid = (tree[index].left+tree[index].right) / 2; if (left <= mid) paint(left, right, color, tree[index].nextLeft); if (right >= mid+1) paint(left, right, color, tree[index].nextRight); } } INT32 count(INT32 left, INT32 right, INT32 index=1) { if (0 == index) return 0; INT32 mask = 0; if (tree[index].color > 0) mask |= alColorShift[ tree[index].color ]; else { INT32 mid = (tree[index].left+tree[index].right) / 2; if (left <= mid) mask |= count(left, right, tree[index].nextLeft); if (right >= mid+1) mask |= count(left, right, tree[index].nextRight); } return mask; } int main() { INT32 i; / init / /// input /// char buffer[256]; INT32 L, T, O, o; scanf("%ld%ld%ld", &L, &T, &O); gets(buffer); /// color /// alColorShift[1] = 1; for (i=2; i<=MAX_COLOR; i++) alColorShift[i] = 1 << (i-1); /// tree /// buildTree(1, 1, L); tree[1].color = 1; / init / / process / for (o=0; o<O; o++) { gets(buffer); char cOpt; cOpt = buffer[0]; switch (cOpt) { case 'C': { INT32 left, right, color; sscanf(buffer+2, "%ld%ld%ld", &left, &right, &color); if (left > right) swap(left, right); paint(left, right, color); } break; case 'P': { INT32 left, right; sscanf(buffer+2, "%ld%ld", &left, &right); if (left > right) swap(left, right); INT32 colorMask = count(left, right); INT32 total = 0; for (i=1; i<=MAX_COLOR; i++) { if (colorMask & alColorShift[i]) total++; } printf("%ld/n", total); } break; default: break; } } / process / return 0; }