首页 > 代码库 > HDU 4902 Nice boat 线段树+离线

HDU 4902 Nice boat 线段树+离线

据说暴力也过了,还傻逼地写了这么长。。。

#include <stdio.h>
#include <string.h>
#include <math.h>
#include <iostream>
using namespace std;
#define ll long long
#define L(x) (x<<1)
#define R(x) (x<<1|1)
#define Val(x) tree[x].val
#define Lazy(x) tree[x].lazy
#define Num(x) tree[x].num
const ll oo = (ll)(-1e15);
inline ll Mid(ll x, ll y){return (x+y)>>1;}
inline ll gcd(ll x, ll y){
    if(x>y)swap(x,y);
    while(x){
        y%=x;
        swap(x,y);
    }
    return y;
}
#define N 100500
struct qqq{
    ll op, l, r, val;
}Q[N];
ll n, a[N];
struct node{
    ll l, r;
    ll lazy, num;
}tree[N<<2];
void push_down(ll id){
    if(tree[id].l == tree[id].r) return;
    if(Num(id)>0){
        Num(L(id)) = Num(R(id)) = Num(id);
    }
    if(Lazy(id) == oo) return;
    Lazy(L(id)) = Lazy(R(id)) = Lazy(id);
    Lazy(id) = oo;
}
void push_up(ll id){
    if(Num(L(id)) != Num(R(id)))
    {
        Num(id) = -1;
    }
    else if(Num(L(id)) == Num(R(id)))Num(id) = Num(L(id));
}
void build(ll l, ll r, ll id){
    tree[id].l = l, tree[id].r = r;
    Lazy(id) = oo;
    Num(id) = 0;
    if(l == r)
    {
        Lazy(id) = a[l];
        return;
    }
    ll mid = Mid(l, r);
    build(l, mid, L(id));
    build(mid+1, r, R(id));
}
void updata1(ll l, ll r, ll val, ll num, ll id){
    push_down(id);
    if(Num(id) > num)return ;
    if(l == tree[id].l && tree[id].r == r && Num(id) == 0)
    {        
        Lazy(id) = val;
        Num(id) = num;
        return;
    }
    ll mid = Mid(tree[id].l, tree[id].r);
    if(mid < l)
        updata1(l, r, val, num, R(id));
    else if(r <= mid)
        updata1(l, r, val, num, L(id));
    else {
        updata1(l, mid, val, num, L(id));
        updata1(mid+1, r, val, num, R(id));
    }
    push_up(id);
}
void updata2(ll l, ll r, ll val, ll num, ll id){
    push_down(id);
    if(Num(id) > num)return ;
    if(l == tree[id].l && tree[id].r == r && Num(id)!=-1)
    {
        if(Lazy(id)!=oo)
        {
            if(Lazy(id) > val)
            Lazy(id) = gcd(Lazy(id), val);
            return ;
        }
    }
    ll mid = Mid(tree[id].l, tree[id].r);
    if(mid < l)
        updata2(l, r, val, num, R(id));
    else if(r <= mid)
        updata2(l, r, val, num, L(id));
    else { 
        updata2(l, mid, val, num, L(id));
        updata2(mid+1, r, val, num, R(id));
    }
    if(Lazy(L(id)) == Lazy(R(id)))
        Lazy(id) = Lazy(L(id));
    else Lazy(id) = oo;
}
void query(ll id){
    push_down(id);
    if(tree[id].l == tree[id].r)
    {
        printf("%I64d ", Lazy(id));
        return ;
    }
    ll mid = Mid(tree[id].l, tree[id].r);
    query(L(id));
    query(R(id));
}
int main(){
    ll i, l, r, T, que, op, val; cin>>T;
    while(T--){
        cin>>n;
        for(i = 1; i <= n; i++)scanf("%I64d",&a[i]);
        build(1, n, 1);
        cin>>que;
        for(i = 1; i <= que; i++)scanf("%I64d %I64d %I64d %I64d", &Q[i].op, &Q[i].l, &Q[i].r, &Q[i].val);
        for(i = que; i; i--)
            if(Q[i].op == 1)
            {
                updata1(Q[i].l, Q[i].r, Q[i].val, i, 1);
            }
        for(i = 1; i <= que; i++)
            if(Q[i].op == 2 && Q[i].op)
            {
                updata2(Q[i].l, Q[i].r, Q[i].val, i, 1);
            }
            query(1);
            puts("");
    }
    return 0;
}