您的位置:首页 > 其它

POJ 2777 解题报告

2014-12-13 10:09 295 查看
这道题看着就是segment tree的题,但是trick的地方很多。

首先是颜色的表示。用int数组的话粗略计算了下感觉会超内存,于是用的是set<int>,可以想到,这使得速度降低了很多。看到discuss上面一个同学说的才恍然大悟,因为color的数目不大于30,所以一个32位int就绰绰有余,而且int的位运算天然地就比set简单快捷。

其次是lazy update。我其实不是很清楚这个有多大影响,不过应该很重要。

再次是POJ的一些特性,g++的时候过不了,改成c++就以900+ms过了。然后将cin, cout改成scanf,printf就有了现在360ms的程序。

2777Accepted3268K360MSC++3762B
/*
ID: thestor1
LANG: C++
TASK: poj2777
*/
#include <iostream>
#include <fstream>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <limits>
#include <string>
#include <vector>
#include <list>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <algorithm>
#include <cassert>

using namespace std;

class Node
{
public:
// as the number of different colors is less than 30, a single int should be sufficient
int colors;
bool delay;
Node() : colors(0), delay(false) {}
};

void update(vector<Node> &segmentTree, int left, int right, int index, const int lindex, const int rindex, const int color)
{
if (lindex <= left && right <= rindex)
{
segmentTree[index].colors = (1 << color);
segmentTree[index].delay = true;
return;
}

if (left != right)
{
int mid = left + ((right - left) >> 1);
if (segmentTree[index].delay)
{
segmentTree[2 * index + 1].colors = segmentTree[index].colors;
segmentTree[2 * index + 1].delay = true;
segmentTree[2 * index + 2].colors = segmentTree[index].colors;
segmentTree[2 * index + 2].delay = true;
segmentTree[index].delay = false;
}

if (rindex <= mid)
{
update(segmentTree, left, mid, 2 * index + 1, lindex, rindex, color);
}
else if (lindex >= mid + 1)
{
update(segmentTree, mid + 1, right, 2 * index + 2, lindex, rindex, color);
}
else
{
update(segmentTree, left, mid, 2 * index + 1, lindex, rindex, color);
update(segmentTree, mid + 1, right, 2 * index + 2, lindex, rindex, color);
}

segmentTree[index].colors = segmentTree[2 * index + 1].colors | segmentTree[2 * index + 2].colors;
}
}

void query(vector<Node> &segmentTree, int left, int right, int index, const int lindex, const int rindex, int &colors)
{
if (lindex <= left && right <= rindex)
{
colors |= segmentTree[index].colors;
return;
}

if (left != right)
{
int mid = left + ((right - left) >> 1);
if (segmentTree[index].delay)
{
segmentTree[2 * index + 1].colors = segmentTree[index].colors;
segmentTree[2 * index + 1].delay = true;
segmentTree[2 * index + 2].colors = segmentTree[index].colors;
segmentTree[2 * index + 2].delay = true;
segmentTree[index].delay = false;
}

if (rindex <= mid)
{
query(segmentTree, left, mid, 2 * index + 1, lindex, rindex, colors);
}
else if (lindex >= mid + 1)
{
query(segmentTree, mid + 1, right, 2 * index + 2, lindex, rindex, colors);
}
else
{
query(segmentTree, left, mid, 2 * index + 1, lindex, rindex, colors);
query(segmentTree, mid + 1, right, 2 * index + 2, lindex, rindex, colors);
}
}
}

int cntcolors(int colors)
{
int cnt = 0;
while (colors)
{
colors &= colors - 1;
cnt++;
}
return cnt;
}

int main()
{
int L, T, O;
// cin >> L >> T >> O;
scanf("%d%d%d", &L, &T, &O);
// cout << "L:" << L << ", T: " << T << ", O: " << O << endl;
vector<Node> segmentTree(4 * L);
update(segmentTree, 0, L - 1, 0, 0, L - 1, 0);

char type;
int a, b, c;

for (int t = 0; t < O; ++t)
{
// cin >> type >> a >> b;
type = 'A';
while (type != 'C' && type != 'P')
{
scanf("%c", &type);
}

scanf("%d%d", &a, &b);
a--, b--;
if (a > b)
{
int tmp = a;
a = b;
b = tmp;
}

if (type == 'C')
{
// color
// cin >> c;
scanf("%d", &c);
c--;
update(segmentTree, 0, L - 1, 0, a, b, c);
}
else
{
// print
int colors = 0;
query(segmentTree, 0, L - 1, 0, a, b, colors);

// cout << "[debug]colors: " << colors << endl;
// cout << cntcolors(colors) << endl;
printf("%d\n", cntcolors(colors));
}
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: