【vijos1066】弱弱的战壕 线段树

描述

永恒和mx正在玩一个即时战略游戏,名字嘛~~~~~~恕本人记性不好,忘了-_-b。

mx在他的基地附近建立了n个战壕,每个战壕都是一个独立的作战单位,射程可以达到无限(“mx不赢定了?!?”永恒ftING…@[email protected])。

但是,战壕有一个弱点,就是只能攻击它的左下方,说白了就是横纵坐标都不大于它的点(mx:“我的战壕为什么这么菜”ToT)。这样,永恒就可以从别的地方进攻摧毁战壕,从而消灭mx的部队。

战壕都有一个保护范围,同它的攻击范围一样,它可以保护处在它左下方的战壕。所有处于它保护范围的战壕都叫做它的保护对象。这样,永恒就必须找到mx的战壕中保护对象最多的点,从而优先消灭它。

现在,由于永恒没有时间来计算,所以拜托你来完成这个任务:

给出这n个战壕的坐标xi、yi,要你求出保护对象个数为0,1,2……n-1的战壕的个数。

输入格式

第一行,一个正整数n(1<=n<=15000)
接下来n行,每行两个数xi,yi,代表第i个点的坐标
(1<=xi,yi<=32000)
注意:可能包含多重战壕的情况(即有数个点在同一坐标)

输出格式

输出n行,分别代表保护对象为0,1,2……n-1的战壕的个数。

样例输入

5
1 1
5 1
7 1
3 3
5 5

样例输出

1

2

1

1

0

代码

#include <cstdio>
#include <cmath>
#include <cstring>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <set>
#include <vector>
#include <sstream>
#include <queue>
#include <typeinfo>
#include <fstream>
#include <map>
#include <stack>
typedef long long ll;
using namespace std;
//freopen("D.in","r",stdin);
//freopen("D.out","w",stdout);
#define sspeed ios_base::sync_with_stdio(0);cin.tie(0)
#define test freopen("test.txt","r",stdin)
#define maxn 200101
#define mod 1000000009
#define eps 1e-9
const int inf=0x3f3f3f3f;
const ll infll = 0x3f3f3f3f3f3f3f3fLL;
inline ll read()
{
    ll x=0,f=1;
    char ch=getchar();
    while(ch<‘0‘||ch>‘9‘)
    {
        if(ch==‘-‘)f=-1;
        ch=getchar();
    }
    while(ch>=‘0‘&&ch<=‘9‘)
    {
        x=x*10+ch-‘0‘;
        ch=getchar();
    }
    return x*f;
}
//**************************************************************************************

struct ss
{
    int r,l,v;
}tr[4*150001];
struct data
{
    int x,y;
}a[15001];
bool cmp(data a,data b){return (a.x==b.x)?(a.y<b.y):(a.x<b.x);}
int ans[15005],n;
void build(int k,int l,int r)
{
    tr[k].l=l;
    tr[k].r=r;
    tr[k].v=0;
    if(l==r) return ;
    int mid=(l+r)>>1;
    build(k<<1,l,mid);
    build(k<<1|1,mid+1,r);
}
void insert(int k,int ls,int rs)
{
    int mid=(tr[k].l+tr[k].r)>>1;
    if(tr[k].l==ls&&tr[k].r==rs)
    {
        tr[k].v++;
        return ;
    }
    else if(tr[k].l==tr[k].r)return ;
    else if(rs<=mid){
        insert(k<<1,ls,rs);
    }
    else if(ls>mid)
    {
        insert(k<<1|1,ls,rs);
    }
    else {
        insert(k<<1,ls,mid);
        insert(k<<1|1,mid+1,rs);
    }
}
int ask(int k,int x)
{
    if(tr[k].l==tr[k].r) return tr[k].v;
    int mid=(tr[k].l+tr[k].r)>>1;
    if(x<=mid)return tr[k].v+(ask(k<<1,x));
    else  return tr[k].v+(ask(k<<1|1,x));
}
int main()
{

    scanf("%d",&n);
    build(1,0,32001);
    for(int i=1;i<=n;i++)
    {
        scanf("%d%d",&a[i].x,&a[i].y);
    }
    sort(a+1,a+n+1,cmp);
    for(int i=1;i<=n;i++)
    {
        ans[ask(1,a[i].y)]++;
        insert(1,a[i].y,32001);
    }
    for(int i=0;i<n;i++)
    {
        printf("%d\n",ans[i]);
    }
    return 0;
}
时间: 2024-10-11 15:44:26

【vijos1066】弱弱的战壕 线段树的相关文章

Vijos P1066 弱弱的战壕【多解,线段树,暴力,树状数组】

弱弱的战壕 描述 永恒和mx正在玩一个即时战略游戏,名字嘛~~~~~~恕本人记性不好,忘了-_-b. mx在他的基地附近建立了n个战壕,每个战壕都是一个独立的作战单位,射程可以达到无限(“mx不赢定了?!?”永恒[email protected][email protected]). 但是,战壕有一个弱点,就是只能攻击它的左下方,说白了就是横纵坐标都不大于它的点(mx:“我的战壕为什么这么菜”ToT).这样,永恒就可以从别的地方进攻摧毁战壕,从而消灭mx的部队. 战壕都有一个保护范围,同它的攻击

【弱校胡策】2016.4.14 (bzoj2164)最短路+状压DP+矩阵乘法+高斯消元+树链剖分+线段树+背包DP

cyyz&qhyz&lwyz&gryz弱校胡策 命题人:cyyz ws_fqk T3暴力写挫了 50+10+0滚粗辣! 奇妙的约会(appointment.cpp/c/pas) [问题描述] DQS和sxb在网上结识后成为了非常好的朋友,并且都有着惊人 的OI水平.在NOI2333的比赛中,两人均拿到了金牌,并保送进入 HU/PKU.于是两人决定在这喜大普奔的时刻进行面基. NOI2333参赛选手众多,所以安排了n个考点,DQS在1号考点, 而sxb在n号考点.由于是举办全国性赛事

弱弱的战壕

弱弱的战壕(jdoj1347-vijos1199) 题目大意:给你n个战壕的坐标,每个战壕只能保护其左下方的战壕 ( 明白为什么是弱弱的战壕了吧 ) ,最后输出n行,第 i 行表示保护了i-1个战壕的战壕个数. 注释:n<=15000 每一个战壕的坐标 ( x ,y ) ,x , y<=32000 想法:和清点人数一样,我们也可以通过线段树来维护,对应的,我们选择树状数组 ( 连修改都没有,扯什么扯 ) .怎么维护呢?我们思考...思考.......其实,我开始的想法是读入,然后统一处理,结果

[FZYZOJ 1003] 弱弱的战壕

P1003 -- 弱弱的战壕 时间限制:1000MS 内存限制:65536KB Description 永恒和lmx正在玩一个即时战略游戏,名字嘛~~~~~~恕本人记性不好,忘了-_-b. mx在他的基地附近建立了n个战壕,每个战壕都是一个独立的作战单位,射程可以达到无限(“lmx不赢定了?!?”永恒[email protected][email protected]). 但是,战壕有一个弱点,就是只能攻击它的左下方,说白了就是横纵坐标都不大于它的点(mx:“我的战壕为什么这么菜”ToT).这样

【vijos】P1066 弱弱的战壕

[算法]线段树 [题解]将所有坐标按x(第一)和y(第二)从小到大排序,再按顺序插入线段树,即在线段树中将y坐标位置+1,这样就能保证每个坐标能包含的点一定先被处理了,每次询问查询1...a[i].y区间的和. #include<cstdio> #include<algorithm> using namespace std; struct cyc{int x,y;}a[15010]; struct treess{int l,r,sum;}t[200010]; const int m

浅谈二维中的树状数组与线段树

一般来说,树状数组可以实现的东西线段树均可胜任,实际应用中也是如此.但是在二维中,线段树的操作变得太过复杂,更新子矩阵时第一维的lazy标记更是麻烦到不行. 但是树状数组在某些询问中又无法胜任,如最值等不符合区间减法的询问.此时就需要根据线段树与树状数组的优缺点来选择了. 做一下基本操作的对比,如下图. 因为线段树为自上向下更新,从而可以使用lazy标记使得矩阵的更新变的高校起来,几个不足就是代码长,代码长和代码长. 对于将将矩阵内元素变为某个值,因为树状数组自下向上更新,且要满足区间加法等限制

【线段树区间合并】HDU1540-Tunnel Warfare

一.题目 Description During the War of Resistance Against Japan, tunnel warfare was carried out extensively in the vast areas of north China Plain. Generally speaking, villages connected by tunnels lay in a line. Except the two at the ends, every village

hihocoder 1080 线段树(区间更新)

题目链接:http://hihocoder.com/problemset/problem/1080 , 两种操作的线段树(区间更新). 这道题前一段时间一直卡着我,当时也是基础不扎实做不出来,今天又想了想其实还是比较简单的,也只能怪自己太弱了. 这道题坑就坑在是有两个操作:set和add,所以lazy标记数组就需要两个,但是有一点要考虑的是一个区间上set与add的先后关系——如果对于一个区间set和add标记同时存在,那么应该如果处理:一种情况set在add之前,那么就按照正常顺序来就可以了:

POJ 2528 Mayor&#39;s posters (hash+线段树成段更新)

题意:有一面墙,被等分为1QW份,一份的宽度为一个单位宽度.现在往墙上贴N张海报,每张海报的宽度是任意的,但是必定是单位宽度的整数倍,且<=1QW.后贴的海报若与先贴的海报有交集,后贴的海报必定会全部或局部覆盖先贴的海报.现在给出每张海报所贴的位置(左端位置和右端位置),问张贴完N张海报后,还能看见多少张海报?(PS:看见一部分也算看到.) 思路:简单的成段更新,但是数据量是1千万,会MT,所以要区间压缩(离散化),保证覆盖的关系不变,离散化的时候有个易错的细节,poj数据水了,这个易错点引用h