萌新求助

P4097 【模板】李超线段树 / [HEOI2013] Segment

resftlmuttmotw @ 2019-12-21 18:01:54

用李超线段树做的

题目 [HEOI2013]Segment

样例没过

谢啦!!

#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define reg register int
#define isdigit(x) ('0' <= x&&x <= '9')
template<typename T>
inline T Read(T Type)
{
    T x = 0,f = 1;
    char a = getchar();
    while(!isdigit(a)) {if(a == '-') f = -1;a = getchar();}
    while(isdigit(a)) {x = (x << 1) + (x << 3) + (a ^ '0');a = getchar();}
    return x * f;
}
const int MAXN = 4e4,mod = 39989,mod2 = 1e9,N = 39989;
namespace lichao_tree
{
    int cnt = 0;
    struct node
    {
        double k,b;
        int flag,l,r;
        node mk(double _k,double _b,int _l,int _r)
        {
            node p;p.k = _k,p.b = _b,p.flag = ++cnt,l = _l,r = _r;
            return p;
        }
        double gety(int x)
        {
            return k * x + b;
        }
    }tree[MAXN << 2],T;
    inline node query(int k,int l,int r,int x)
    {
        if(l == r) return tree[k];
        int mid = l + r >> 1;
        node g;
        if(x <= mid) 
        {
            g = query(k << 1,l,mid,x);
            printf("{%d,%d,%d}\n",l,mid,g.flag);
        }
        else {
            g = query(k << 1 | 1,mid + 1,r,x);
            printf("{%d,%d,%d}\n",mid + 1,r,g.flag);
        }
        if(g.gety(x) > tree[k].gety(x)) return g;
        return tree[k];
    }
    inline void build(int k,int l,int r)
    {
        tree[k].l = tree[k].r = 0;
        tree[k].b = tree[k].k = tree[k].flag = 0;
        if(l == r) return;
        int mid = l + r >> 1;
        build(k << 1,l,mid);
        build(k << 1 | 1,mid + 1,r);
    }
    inline void insert(int k,int l,int r,node p)
    {
        if(p.l <= l&&r <= p.r)
        {
            if(!tree[k].flag||(p.gety(l) >= tree[k].gety(l)&&p.gety(r) >= tree[k].gety(r)))
            {
                tree[k] = p;
                return;
            }
            if(l == r||(p.gety(l) <= tree[k].gety(l)&&p.gety(r) <= tree[k].gety(r))) return;
            int mid = l + r >> 1;
            if(p.gety(mid) > tree[k].gety(mid)) swap(p,tree[k]);
            if(p.gety(l) >= tree[k].gety(l)) insert(k << 1,l,mid,p);
            if(p.gety(r) >= tree[k].gety(r)) insert(k << 1 | 1,mid + 1,r,p);
            return;
        }
        int mid = l + r >> 1;
        if(p.l <= mid) insert(k << 1,l,mid,p);
        if(mid < p.r) insert(k << 1 | 1,mid + 1,r,p);
    }
}
using namespace lichao_tree;
int main()
{
    int n = Read(1),last_ = 0;
    build(1,1,N);
    while(n--)
    {
        int c = Read(1);
        if(c & 1)
        {
            int x[2],y[2];
            for(reg i = 0;i < 2;i++) x[i] = (Read(1) + last_ - 1) % mod + 1,y[i] = (Read(1) + last_ - 1) % mod2 + 1;
            if(x[0] == x[1]) continue;
            if(x[0] > x[1]) swap(x[0],x[1]),swap(y[0],y[1]);
            double k = 1.0 * (y[1] - y[0]) / (x[1] - x[0]);
            insert(1,1,N,T.mk(k,y[1] - 1.0 * x[1] * k,x[0],x[1]));
//          printf("[%f,%f]\n",x[0],x[1]);
        } else {
            int x = (Read(1) + last_ - 1) % mod + 1;
//          printf("[%d]\n",x);
            last_ = query(1,1,N,x).flag;
            printf("%d\n",last_);
        }
    }
    return 0;
}

by Rintaro @ 2019-12-27 22:11:02

样例没过先调一下样例呀。。


|