UVA 12647 Balloon (线段树) URAL 1915 Titan Ruins: Reconstruction of Bygones (暴力,树状数组)

UVA 12647  Balloon (线段树)  

URAL 1915 Titan Ruins: Reconstruction of Bygones (树状数组或暴力)


这两题都是转化后变成区间更新和点查询的问题(第二题是可以暴力的)!!!

第一题,转化为,区间覆盖,点值查询,(每个点记录的其上面一个线段的id)

第二题,转化为,区间加减值,点值查询,(每个点记录于其上一个点位置的差值)


两题都有,A-->B-->C的数据传递关系,则要求C,则需求B,求B则需求A;

则C记录到达B的方法,B记录到达A的方法,就可以有C,求C的相关的A的信息了

其中,第一题,C通过记录B的id找到B,再由B记录的A的id,找到A

第二题,C通过记录与B位置的差值找到B,再由B记录的与A的位置的差值,找到A


UVA 12647  Balloon (线段树)  参考队友从中山大学大牛借的代码

#include<functional>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>
#include<string>
#include<queue>
#include<map>
#include<set>
#define REP(i, n) for(int i=0; i<n; i++)
#define FF(i, a, b) for(int i=a; i<b; i++)
#define FD(i, a, b) for(int i=a; i>=b; i--)
#define LL long long
#define PB push_back
#define MP make_pair
#define PII pair<int, int>
#define xx first
#define yy second
#define CLR(a, b) memset(a, b, sizeof(a))
#define debug puts("****debug****")
using namespace std;
const int INF = 0x3f3f3f3f;
const int N = 1000010;
const int maxn = 100010;

#define lson l, m, rt << 1
#define rson m + 1, r, rt << 1 | 1
int cover[N << 2];
int c[N << 2];
int f[maxn], ansx[maxn];
int n, m;
struct seg{
    int x1, y1, x2, y2;
    bool operator<(const seg &b) const
    {
        return y1 < b.y1;
    }
}g[maxn];

void pushdown(int rt)
{
    if (cover[rt] != -1)///!!!
    {
        cover[rt << 1] = cover[rt << 1 | 1] = cover[rt], cover[rt] = -1;
    }
}
void update(int L, int R, int i, int l, int r, int rt)
{
    if (L <= l && r <= R)
    {
        cover[rt] = i;
        return ;
    }
    int m = (l + r) >> 1;
//    pushdown(rt);
    if (cover[rt] != -1)
    cover[rt << 1] = cover[rt << 1 | 1] = cover[rt], cover[rt] = -1;
    if (L <= m) update(L, R, i, lson);
    if (R > m) update(L, R, i, rson);
}

int query(int x, int l, int r, int rt)
{
    if (cover[rt] >= 0)
        return cover[rt];
    int m = (l + r) >> 1;
//    pushdown(rt);
    if (cover[rt] != -1)
    cover[rt << 1] = cover[rt << 1 | 1] = cover[rt], cover[rt] = -1;
    if (x <= m) return query(x, lson);
    else return query(x, rson);
}

void solve()
{
//    CLR(cover, -1);///!!!
    sort(g, g + n + 1);
    FD(i, n, 0)
    {
        if (g[i].y1 == g[i].y2)
            f[i] = i;
        else
        {
            int k = query(g[i].x1, 0, N, 1);
            f[i] = f[k];
            if (g[k].y1 == g[k].y2)
                ansx[i] = g[i].x1;///!!!
            else
                ansx[i] = ansx[k];
        }
        int L = g[i].x1, R = g[i].x2;
        if (L > R) swap(L, R);
        update(L, R, i, 0, N, 1);
    }
}

void fun(int x)
{
    int k = query(x, 0, N, 1);
    if (g[k].y1 != g[k].y2) x = ansx[k];///!!!
    if (f[k] == n) printf("%d\n", x);
    else printf("%d %d\n", x, g[f[k]].y1);
}

int main()
{
    int x;
    while (~scanf("%d%d", &n, &m))
    {
        REP(i, n)
        {
            scanf("%d%d%d%d", &g[i].x1, &g[i].y1, &g[i].x2, &g[i].y2);
            if (g[i].y1 < g[i].y2) swap(g[i].x1, g[i].x2), swap(g[i].y1, g[i].y2);
        }
        g[n].x1 = 0; g[n].y1 = N + 1; g[n].x2 = N; g[n].y2 = N + 1;
        solve();
        while (m--)
        {
            scanf("%d", &x);
            fun(x);
        }
    }
    return 0;
}
URAL 1915 Titan Ruins: Reconstruction of Bygones (树状数组或暴力)

参考:http://blog.csdn.net/ok_again

//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <cstdio>
#include <ctime>
#include <cstdlib>
#include <cstring>
#include <queue>
#include <string>
#include <set>
#include <stack>
#include <map>
#include <cmath>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;

#define FF(i, a, b) for(int i = (a); i < (b); ++i)
#define FE(i, a, b) for(int i = (a); i <= (b); ++i)
#define FD(i, b, a) for(int i = (b); i >= (a); --i)
#define REP(i, N) for(int i = 0; i < (N); ++i)
#define CLR(a, v) memset(a, v, sizeof(a))
#define PB push_back
#define MP make_pair

typedef long long LL;
const int INF = 0x3f3f3f3f;
const int N = 2000000;

int a[N + 10], s[N + 10];
inline int lowbit(int x)
{
    return x & (-x);
}
void add(int i, int v)
{
    for (; i <= N; i += lowbit(i))
        s[i] += v;
}
int sum(int i)
{
    int ret = 0;
    for (; i > 0; i -= lowbit(i))
        ret += s[i];
    return ret;
}

int realidx(int x)
{
    int ad = sum(x);
    while (ad != 0)
    {
        x += ad;
        ad = sum(x);
    }
    return x;
}
int n;
int main ()
{
    int x;
    scanf("%d", &n);
    int num = 1;///数的个数
    ///CLR(s, 0);
    while (n--)
    {
        scanf("%d", &x);
        if (x > 0) a[num++] = x;
        else if (x == 0)
        {
            if (num > n + 5) continue;
            add(num, 1 - num);
            add(2 * (num - 1) + 1, num - 1);
            num += num - 1;
        }
        else
        {
            printf("%d\n", a[realidx(--num)]);
            ///s[num] = 0;///wa
            int ad = sum(num);
            add(num, -ad);
            add(num + 1, ad);
        }
    }
    return 0;
}


  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值