Problem Address:http://acm.hdu.edu.cn/showproblem.php?pid=3577
线段树不是特别熟悉。
特别是关于更新区间查询区间的。
用到了延迟标记,稍微理解了一下。
这道题不用离散化也可以。
不过一百万的区间,离散化后只有十万,时空复杂度都上了一个档次。
#include <iostream>
#include <map>
using namespace std;
map<int, int>hash;
map<int, int>::iterator it;
const int maxn = 100000;
#define lson l, m, rt<<1
#define rson m+1, r, rt<<1|1
int hashindex;
struct node
{
int x, y;
}bn[maxn+5];
inline int max(int a, int b)
{
if (a>=b) return a;
else return b;
}
struct treenode
{
int max, add;
}tree[maxn<<2];
void pushup(int rt)
{
tree[rt].max = max(tree[rt<<1].max, tree[rt<<1|1].max);
}
void pushdown(int rt)
{
if (tree[rt].add)
{
tree[rt<<1].add += tree[rt].add;
tree[rt<<1|1].add += tree[rt].add;
tree[rt<<1].max += tree[rt].add;
tree[rt<<1|1].max += tree[rt].add;
tree[rt].add = 0;
}
}
void buildtree(int l, int r, int rt)
{
tree[rt].max = 0;
tree[rt].add = 0;
if (l==r) return;
int m = (l+r)>>1;
buildtree(lson);
buildtree(rson);
// pushup(rt);
}
int getmax(int L, int R, int l, int r, int rt)
{
if (L<=l && R>=r)
{
return tree[rt].max;
}
pushdown(rt);
int m = (l+r)>>1;
int res = 0;
if (L<=m) res = getmax(L, R, lson);
if (R>m) res = max(res, getmax(L, R, rson));
return res;
}
void add(int L, int R, int l, int r, int rt)
{
if (L<=l && R>=r)
{
tree[rt].add++;
tree[rt].max++;
return;
}
pushdown(rt);
int m = (l+r)>>1;
if (L<=m) add(L, R, lson);
if (R>m) add(L, R, rson);
pushup(rt);
}
int main()
{
int t, index;
int k, q;
int i;
int l, r;
scanf("%d", &t);
for (index=1; index<=t; index++)
{
hash.clear();
hashindex = 0;
scanf("%d %d", &k, &q);for (i=1; i<=q; i++)
{
scanf("%d %d", &bn[i].x, &bn[i].y);
if (hash.find(bn[i].x)==hash.end()) hash[bn[i].x] = 1;
if (hash.find(bn[i].y)==hash.end()) hash[bn[i].y] = 1;
}
for (it=hash.begin(); it!=hash.end(); it++)
{
(*it).second = ++hashindex;
}
buildtree(1, maxn, 1);
printf("Case %d:\n", index);
for (i=1; i<=q; i++)
{
l = hash[bn[i].x];
r = hash[bn[i].y];
r--;
if (getmax(l, r, 1, maxn, 1)<k)
{
add(l, r, 1, maxn, 1);
printf("%d ", i);
}
}
printf("\n");
printf("\n");
}
return 0;
}