zoukankan      html  css  js  c++  java
  • HDU 4027 Can you answer these queries?

    http://acm.hdu.edu.cn/showproblem.php?pid=4027

    题目

    给出一串数字,表示一排战舰的耐久度= =

    有两种操作

    1. 使用武器,把从x到y的每一个战舰的耐久度开平方,向下取整
    2. 查询从x到y的战舰的耐久度的和,保证和不会超过$2^{63}$

    100000个战舰,100000操作,2s时限

    题解

    开根号没有什么好的区间性质,看不到什么好的线段树的特点……

    不过开根号开到几次再开就不会变了,可以用这个性质设定一个区间开关之类的东西,到不会变的区间就不再修改

    这样最多执行6*100000次开方,可以卡进时限= =

    另外线段树在递归的时候是数学归纳,递归的区间一定是与操作的区间相交的,于是要保证下一层也相交,只用考虑递归的区间的中点与查询区间中点的关系

    因为相交,所以不存在红框的情况,所以判断左子区间是否与黄框相交就可以了,还要注意右区间是[m+1,r]

    由于是从x到y,所以不能把l,r直接和x,y对应,还需要考虑大小

    AC代码

    #include<bits/stdc++.h>
    using namespace std;
    
    #define REP(r,x,y) for(int r=(x); r<y; r++)
    #define REPE(r,x,y) for(int r=(x); r<=y; r++)
    #define PERE(r,x,y) for(int r=(x); r>=y; r++)
    
    typedef long long LL;
    
    #define MAXN 100007
    struct node {
        int l,r;
        LL v;
        int d;
    }t[MAXN<<2];
    int n,m;
    LL e[MAXN];
    
    void build(int p, int l, int r) {
        node &now = t[p];
        now.l=l, now.r=r;
        now.d=1;
        if(l==r) {
            now.v=e[l];
            return;
        }
        int m=l+r>>1;
        build(p*2,l,m);
        build(p*2+1,m+1,r);
        now.v=t[p*2].v+t[p*2+1].v;
    }
    
    void ope(int p, int l, int r) {
        node &now = t[p];
        if(now.l==now.r) {
            now.v=(int)floor(sqrt(now.v));
            if(now.v<=1) now.d=0;
            return;
        }
        int m=now.l+now.r>>1;
        if(m>=l && t[p*2].d) ope(p*2, l, r);
        if(m+1<=r && t[p*2+1].d) ope(p*2+1, l, r);
    
        now.d= t[p*2].d || t[p*2+1].d;
        now.v=t[p*2].v+t[p*2+1].v;
    }
    
    LL opq(int p, int l, int r) {
        node &now = t[p];
        if(now.l>=l && now.r<=r) {
            return now.v;
        }
        int m=(now.l+now.r)>>1;
        LL ans=0;
        if(m>=l) ans+=opq(p*2, l, r);
        if(m+1<=r) ans+=opq(p*2+1,l,r);
        return ans;
    }
    
    int main() {
        #ifdef sahdsg
        freopen("in.txt", "r", stdin);
        #endif // sahdsg
        int kase=0;
        while(~scanf("%d", &n)) {
            printf("Case #%d:
    ", ++kase);
            REPE(i,1,n) {
                scanf("%lld", &e[i]);
            }
            build(1,1,n);
            scanf("%d", &m);
            REP(i,0,m) {
                int T,x,y;
                scanf("%d%d%d", &T, &x, &y);
                if(x>y) swap(x,y);
                if(T==0) ope(1,x,y);
                else {
                    printf("%lld
    ", opq(1,x,y));
                }
            }
            putchar('
    ');
        }
    
        return 0;
    }
    
  • 相关阅读:
    Leetcode 5
    DFS输出全排列
    Leetcode 461
    Leetcode 4
    Leetcode 3
    Leetcode 2
    Windows 10 Mac 为Vs Code配置C/C++环境
    机器学习 学习笔记(1) -- 初识机器学习
    MacBook Pro休眠掉电、耗电量大问题解决方案
    Oracle错误及解决方案
  • 原文地址:https://www.cnblogs.com/sahdsg/p/10985179.html
Copyright © 2011-2022 走看看