hdu5239Doom 线段树+找规律

来源:互联网 发布:html中js用函数传值 编辑:程序博客网 时间:2024/04/30 17:25
//给出n个数据 , 对于每次[l,r]//操作,s加上[l,r]区间的所有数//之和,并且将[l,r]区间的所有数//都平方//输出s%9223372034707292160 //打表可以发现对于每个数在做一定操作//后其值一定不变//所以只需要维护一个标记就行#include<cstdio>#include<cstring>#include<iostream>using namespace std ;const int maxn = 1e5+10 ;typedef unsigned long long ll ;const ll mod = 9223372034707292160 ;#define left v<<1#define right v<<1|1struct node{    int l , r ;    ll  v ;    int cnt ;}tree[maxn<<2] ;ll mul(ll a , ll b){    ll c = 0 ;    while(b)    {        if(b&1)        {            c+= a ;            if(c >= mod)c-=mod ;        }        a += a ;        if(a >= mod)a-=mod ;        b >>= 1 ;    }    return c ;}void push_up(int v){    tree[v].v = tree[left].v + tree[right].v ;    if(tree[v].v >= mod)tree[v].v -= mod ;    if(tree[left].cnt && tree[right].cnt)    tree[v].cnt = 1 ; }void build(int l , int r , int v){    tree[v].l = l ;    tree[v].r = r ;    tree[v].cnt = 0 ;    if(l == r)    {        scanf("%I64u" , &tree[v].v) ;        if(tree[v].v >= mod)tree[v].v -= mod ;        return  ;    }    int mid = (l + r) >> 1 ;    build(l , mid , left) ;    build(mid+1 , r , right) ;    push_up(v) ;}ll update(int l , int r , int v){    if(l <= tree[v].l && tree[v].r <= r)        if(tree[v].cnt)        return tree[v].v ;    if(tree[v].l == tree[v].r)    {        ll tmp = tree[v].v ;        tree[v].v = mul(tmp , tmp) ;        if(tree[v].v == mul(tree[v].v , tree[v].v))        tree[v].cnt = 1;        return tmp ;    }    int mid = (tree[v].l + tree[v].r) >> 1 ;    ll ans = 0 ;    if(l <= mid){        ans+=update(l , r , left) ;        if(ans >= mod)ans-=mod ;    }    if(r > mid){        ans+= update(l , r , right) ;        if(ans >= mod)ans-=mod ;    }    push_up(v) ;    return ans ;}int main(){    int t ;    scanf("%d" ,&t) ;    int cas = 0 ;    while(t--)    {        int n , m ;        scanf("%d%d" ,&n , &m) ;        build(1 , n , 1) ;        ll s = 0 ;        printf("Case #%d:\n" , ++cas) ;        while(m--)        {            int l , r ;            scanf("%d%d"  , &l , &r) ;            s += update(l , r , 1) ;            if(s >= mod)s-=mod ;            printf("%I64u\n" , s) ;        }    }    return  0 ;}
0 0
原创粉丝点击