hdu4973A simple simulation problem. 线段树

来源:互联网 发布:仁王pc版帧数优化补丁 编辑:程序博客网 时间:2024/06/06 09:03
//n(n<=5e4+10)个格子,每个格子的初始值为1//m(m<=5e4+10)个询问//D l r 将区间l,r的所有点翻倍//D l r 问区间l,r中格子中最多的数//线段树维护三个值,ss(区间的所有值之和),ma(区间中的最大值)//mm(区间需要乘2的多少次方)#include<cstdio>#include<cstring>#include<iostream>using namespace std  ;const int maxn = 5e4+10 ;#define left v<<1#define right v<<1|1typedef long long ll ;struct Tree{    int l , r ;    int mm;    ll ss ;    ll ma ;}tree[maxn<<2] ;void push_up(int v){    tree[v].ma = max(tree[left].ma , tree[right].ma) ;    tree[v].ss = tree[left].ss + tree[right].ss ;}void push_down(int v){    if(tree[v].mm){        ll tmp = ((ll)1)<<tree[v].mm ;        tree[left].ss *= tmp ;        tree[left].ma *= tmp ;        tree[left].mm += tree[v].mm ;        tree[right].ss *= tmp ;        tree[right].ma *= tmp ;        tree[right].mm += tree[v].mm ;        tree[v].mm = 0 ;    }}void build(int l , int r , int v){    tree[v].l = l ;    tree[v].r = r;    tree[v].mm = 0 ;    if(l == r){        tree[v].ma = tree[v].ss = 1;        return ;    }    int mid = (l + r) >> 1 ;    build(l , mid , left) ;    build(mid+1,r,right) ;    push_up(v)  ;}void update(int l , int r , int v){    if(l <= tree[v].l && tree[v].r <= r){         tree[v].ss *= 2 ;         tree[v].ma *= 2 ;         tree[v].mm++;         return  ;    }    push_down(v) ;    int mid = (tree[v].l + tree[v].r) >> 1 ;    if(l <= mid)update(l,r,left) ;    if(r > mid)update(l,r,right) ;    push_up(v) ;}struct node{    ll pp ,ss , xx ;};node query(ll x , int v){    if(tree[v].l == tree[v].r)         return node{tree[v].l , tree[v].ss , x} ;     push_down(v) ;     node ans ;     if(tree[left].ss >= x)         ans = query(x , left) ;     else ans = query(x-tree[left].ss , right) ;     push_up(v) ;     return ans ;}void add(int pos , ll x , int v){    if(tree[v].l == tree[v].r){        tree[v].ma += x ;        tree[v].ss += x ;        return ;    }    push_down(v) ;    int mid = (tree[v].l + tree[v].r) >> 1 ;    if(pos <= mid)add(pos , x , left) ;    else add(pos , x , right) ;    push_up(v) ;}ll get_ans(int l , int r , int v){    if(l <= tree[v].l && tree[v].r <= r)        return tree[v].ma ;    push_down(v) ;    int mid = (tree[v].l + tree[v].r) >> 1 ;    ll ans = 0 ;    if(l <= mid)ans = max(ans , get_ans(l,r,left)) ;    if(r > mid) ans = max(ans , get_ans(l,r,right)) ;    push_up(v) ;    return ans  ;}int main(){    int t ;    int cas = 0 ;    scanf("%d" , &t) ;    while(t--)    {        int n , m ;        scanf("%d%d" , &n , &m) ;        build(1,n,1) ;        char ch[5] ;        ll l , r ;        printf("Case #%d:\n" , ++cas) ;        while(m--)        {            scanf("%s%lld%lld" , ch , &l , &r) ;            node p1 = query(l,1) ;            node p2 = query(r,1) ;            if(ch[0] == 'D'){                if(p1.pp == p2.pp)                    add(p1.pp,r-l+1,1) ;                else{                    add(p1.pp,p1.ss-p1.xx+1,1) ;                    add(p2.pp,p2.xx,1) ;                    update(p1.pp+1,p2.pp-1,1) ;                }            }            else {                if(p1.pp == p2.pp)                    printf("%lld\n" , r-l+1) ;                else{                    ll ans = max(p1.ss-p1.xx+1,p2.xx)  ;                    ans  = max(ans , get_ans(p1.pp+1,p2.pp-1,1)) ;                    printf("%lld\n" , ans) ;                }            }        }    }    return 0 ;}

0 0
原创粉丝点击