离散化+线段树简单例题
POJ 2528
求没有被完全覆盖的海报(不知道是不是这个意思)有多少张。注意题目一开始给的数字不是线段的端点而是线段。所以离散化的时候需要先处理,也就是把右端点+1.然后离散化,插入的时候应该插入线段,所以应该插入(left, right-1)。然后查询只需查询一次,标记即可。
ZOJ 2301, HDU 1199
做法是一样的,都是一维线段树,比较好处理。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <cmath>
#include <ctime>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <string>
#include <bitset>
#include <vector>
#include <deque>
#include <utility>
#include <list>
#include <sstream>
#include <iostream>
#include <fstream>
#include <functional>
#include <numeric>
#include <algorithm>
using namespace std;
//TEMPLATE_BY_LIKE
#define EP 1E-10
#define CLR(arr, v) memset(arr, v, sizeof(arr))
#define SQ(a) ((a)*(a))
#define DEBUG(a) printf("%s = %s\n", #a, toStr(a).c_str())
#define FOR(i,s,e) for( int (i)=(s); (i) < (e) ; i++)
#define SIZE(X) ((int)(X.size()))
#define LENGTH(X) ((int)(X.length()))
#define two(X) (1<<(X))
#define twoL(X) (((int64)(1))<<(X))
typedef long long LL;
typedef unsigned long long uLL;
const double PI = acos(-1.0);
int toInt(string s) {int r=0; istringstream sin(s); sin>>r; return r;}
LL toInt64(string s) {LL r=0; istringstream sin(s); sin>>r; return r;}
double toDouble(string s){double r=0; istringstream sin(s); sin>>r; return r;}
double dist(double x1, double y1, double x2, double y2){return sqrt(SQ(x1-x2)+SQ(y1-y2));}
bool isUpperCase(char c){return c >= 'A' && c <= 'Z';}
bool isLowerCase(char c){return c >= 'a' && c <= 'z';}
bool isLetter(char c) {return c >= 'A' && c <= 'Z' || c >= 'a' && c <= 'z';}
bool isDigit(char c) {return c >= '0' && c <= '9';}
char toLowerCase(char c){return (isUpperCase(c))?(c + 32) : c;}
char toUpperCase(char c){return (isLowerCase(c))?(c - 32) : c;}
template<class T> inline T strTo(string s){istringstream is(s);T v;is>>v;return v;}
template<class T> inline string toStr(const T& v){ostringstream os;os<<v;return os.str();}
template<class T> inline int cMin(T& a, const T& b){return b<a?a=b,1:0;}
template<class T> inline int cMax(T& a, const T& b){return a<b?a=b,1:0;}
template<class T> inline int cBit(T n){return n?cBit(n&(n-1))+1:0;}
template<class T> inline T lowbit(T n){return (n^(n-1))&n;}
template<class T> inline T GCD(T a, T b)
{if(a<0)return GCD(-a,b);if(b<0)return GCD(a,-b);return (b==0)?a:GCD(b,a%b);}
template<class T> inline T LCM(T a, T b)
{if(a<0)return LCM(-a,b);if(b<0)return LCM(a,-b);return a*(b/gcd(a,b));}
//TEMPLATE_BY_LIKE
struct TNode{
int l, r;
int color;
bool cover;
TNode *left, *right;
};
TNode tree[50000];
int ncount;
void buildTree(TNode *root, int l, int r){
root->l = l;
root->r = r;
root->cover = true;
root->color = 1;
if (l != r){
ncount++;
root->left = tree + ncount;
ncount++;
root->right = tree + ncount;
buildTree(root->left, l, (l + r) / 2);
buildTree(root->right, (l + r) / 2 + 1, r);
}
}
void insert(TNode *root, int l, int r, int col){
if (root->cover && root->color == col)
return;
if (root->l == l && root->r == r){
root->cover = true;
root->color = col;
return;
}
if (root->cover){
root->cover = false;
root->left->cover = true;
root->right->cover = true;
root->left->color = root->color;
root->right->color = root->color;
}
if (root->r != root->l){
int mid = (root->l + root->r) / 2;
if (mid < l)
insert(root->right, l, r, col);
else if (mid >= r)
insert(root->left, l, r, col);
else {
insert(root->left, l, mid, col);
insert(root->right, mid + 1, r, col);
}
}
}
bool vis[5000];
void query(TNode *root, int l, int r){
if (root->cover){
if (root->color == 2){
for (int i = root->l; i <= root->r; i++)
vis[i] = true;
}
return;
}
if (root->l - root->r){
int mid = (root->l + root->r) / 2;
if (mid < l)
query(root->right, l, r);
else if (mid >= r)
query(root->left, l, r);
else {
query(root->left, l, mid);
query(root->right, mid + 1, r);
}
}
}
map<int, int> ma;
struct node{
int start, end, col;
};
node d[2100];
int p[5000], q[5000];
int main() {
int n;
while (~scanf("%d", &n)){
int t = 0;
ma.clear();
for (int i = 0; i < n; i++) {
char c[3];
scanf("%d%d%s", &d[i].start, &d[i].end, c);
d[i].end++;
if (d[i].start > d[i].end){
int t = d[i].start;
d[i].start = d[i].end;
d[i].end = t;
}
if (c[0] == 'w'){
d[i].col = 2;
}else d[i].col = 1;
p[t++] = d[i].start;
p[t++] = d[i].end;
}
sort(p, p + t);
int k = 0;
ma[p[0]] = ++k;
q[k] = p[0];
for (int i = 1; i < t; i++)
if (p[i] != p[i - 1]) {
ma[p[i]] = ++k;
q[k] = p[i];
}
ncount = 0;
buildTree(tree, 1, k);
for (int i = 0; i < n; i++) {
int a = ma[d[i].start], b = ma[d[i].end];
insert(tree, a, b - 1, d[i].col);
}
CLR(vis, 0);
query(tree, 1, k);
int maxlen = -1, s = 1;
int l1 = 0, l2 = 0;
bool flag = false;
for (int i = 1; i <= k; i++){
if (!vis[i] && vis[i - 1]){
if (maxlen < q[i] - 1 - q[s]){
maxlen = q[i] - 1 - q[s];
l1 = q[s];
l2 = q[i] - 1;
flag = true;
}
}
if (vis[i] && !vis[i - 1])
s = i;
}
if (maxlen < q[k] - q[s] && vis[k]){
l1 = q[s];
l2 = q[k];
flag = true;
}
if(!flag)printf("Oh, my god\n");
else
printf("%d %d\n", l1, l2);
}
return 0;
}
浙公网安备 33010602011771号