P4145 上帝造题的七分钟2 / 花神游历各国

思路

每个数不会被开方超过log次,对每个数暴力开方即可

代码

#include <algorithm>
#include <cstring>
#include <cstdio>
#include <cmath>
#define int long long
using namespace std;
struct Node{
    int max,sum;
}Seg[100100<<2];
int a[100100],n,m;
void pushup(int o){
    Seg[o].sum=Seg[o<<1].sum+Seg[o<<1|1].sum;
    Seg[o].max=max(Seg[o<<1].max,Seg[o<<1|1].max);
}
void build(int l,int r,int o){
    if(l==r){
        Seg[o].sum=Seg[o].max=a[l];
        return;
    }
    int mid=(l+r)>>1;
    build(l,mid,o<<1);
    build(mid+1,r,o<<1|1);
    pushup(o);
}
void modi(int L,int R,int l,int r,int o){
    if(Seg[o].max<=1)
        return;
    if(l==r){
        Seg[o].max=Seg[o].sum=sqrt(Seg[o].sum);
        return;
    }
    int mid=(l+r)>>1;
    if(L<=mid)
        modi(L,R,l,mid,o<<1);
    if(R>mid)
        modi(L,R,mid+1,r,o<<1|1);
    pushup(o);
}
int query(int L,int R,int l,int r,int o){
    if(L<=l&&r<=R){
        return Seg[o].sum;
    }
    int mid=(l+r)>>1,ans=0;
    if(L<=mid)
        ans+=query(L,R,l,mid,o<<1);
    if(R>mid)
        ans+=query(L,R,mid+1,r,o<<1|1);
    return ans;
}
signed main(){
    scanf("%lld",&n);
    for(int i=1;i<=n;i++)
        scanf("%lld",&a[i]);
    build(1,n,1);
    scanf("%lld",&m);
    for(int i=1;i<=m;i++){
        int opt,l,r;
        scanf("%lld %lld %lld",&opt,&l,&r);
        if(l>r)
            swap(l,r);
        if(opt==0)
            modi(l,r,1,n,1);
        else
            printf("%lld\n",query(l,r,1,n,1));
    }
    return 0;
}

原文地址:https://www.cnblogs.com/dreagonm/p/10549793.html

时间: 2024-10-31 22:07:19

P4145 上帝造题的七分钟2 / 花神游历各国的相关文章

luogu P4145 上帝造题的七分钟2 / 花神游历各国 维护区间和&amp;&amp;区间开根号

因为开根号能使数字减小得非常快 所以开不了几次(6次?)很大的数就会变成1..... 所以我们可以维护区间最大值,若最大值>1,则继续递归子树,暴力修改叶节点,否则直接return (好像也可以维护区间被开方的次数,但我不会...QAQ) #include<cstdio> #include<iostream> #include<cmath> #define int long long #define R register int #define ls (tr<

上帝造题的七分钟2 / 花神游历各国

好吧,楼下有分块的解法,那么我就再阐述一遍好了 本以为暴力分块为\(TLE\)的,结果发现吊打线段树,用奇技淫巧的卡常技术卡到第一页 评测记录 其实这道题就是数列分块入门\(5\)嘛,发现一个数只能被不超过\(6\)次开方,那么暴力修改,用一个标记看看整块是否有大于\(1\)的数 那么我就献上一个未卡常的分块解法 \(Code\ Below:\) #include <bits/stdc++.h> #define ll long long using namespace std; const i

洛谷P4145上帝造题的七分钟——区间修改

题目:https://www.luogu.org/problemnew/show/P4145 区间开平方,可以发现其实开几次就变成1,不需要开了,所以标记一下,每次只去开需要开的地方: 原来写的并查集跳过1或0,然而WA... (如果a数组<原数组>开int会RE!) 改成线段树,本来想着是这一段区间和只要小于等于其长度就可以跳过了,然而仔细想想完全不是,应为可能有多个0什么的: 所以直接开bool数组标记一下就好了: 不需要pushdown,直接去修改或是跳过. 并查集: #include&

【BZOJ3211&amp;3038】花神游历各国&amp;上帝造题的七分钟2(CodeVS)

Description Input Output 每次x=1时,每行一个整数,表示这次旅行的开心度 Sample Input 4 1 100 5 5 5 1 1 2 2 1 2 1 1 2 2 2 3 1 1 4 Sample Output 101 11 11 HINT 对于100%的数据, n ≤ 100000,m≤200000 ,data[i]非负且小于10^9 Source SPOJ2713 gss4 数据已加强 思路:线段树并不能区间开方,但直接暴力修改是会超时的,只要加入一点点优化:若

BZOJ 3038 上帝造题的七分钟2 (并查集+树状数组)

题解:同 BZOJ 3211 花神游历各国,需要注意的是需要开long long,还有左右节点需要注意一下. #include <cstdio> #include <cmath> #include <iostream> #include <algorithm> using namespace std; typedef long long LL; LL a[100005],c[100005]; int f[100005],n,m,op,l,r,t; int s

【BZOJ3038】【Codevs2492】上帝造题的七分钟2

喜闻乐见双倍经验 2492 上帝造题的七分钟 2 时间限制: 1 s 空间限制: 64000 KB 题目等级 : 大师 Master 题目描述 Description XLk觉得<上帝造题的七分钟>不太过瘾,于是有了第二部. "第一分钟,X说,要有数列,于是便给定了一个正整数数列. 第二分钟,L说,要能修改,于是便有了对一段数中每个数都开平方(下取整)的操作. 第三分钟,k说,要能查询,于是便有了求一段数的和的操作. 第四分钟,彩虹喵说,要是noip难度,于是便有了数据范围. 第五分

BZOJ 3132: 上帝造题的七分钟( 二维BIT )

二维树状数组... 自己YY一下再推一下应该可以搞出来... ---------------------------------------------------------------------------------- #include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #define rep( i , n ) for( int i = 0 ; i <

3038: 上帝造题的七分钟2 [线段树 暴力]

3038: 上帝造题的七分钟2 Time Limit: 3 Sec  Memory Limit: 128 MBSubmit: 1210  Solved: 536[Submit][Status][Discuss] Description XLk觉得<上帝造题的七分钟>不太过瘾,于是有了第二部."第一分钟,X说,要有数列,于是便给定了一个正整数数列.第二分钟,L说,要能修改,于是便有了对一段数中每个数都开平方(下取整)的操作.第三分钟,k说,要能查询,于是便有了求一段数的和的操作.第四分

Bzoj3038 上帝造题的七分钟2 并查集

Time Limit: 3 Sec  Memory Limit: 128 MBSubmit: 1135  Solved: 509 Description XLk觉得<上帝造题的七分钟>不太过瘾,于是有了第二部."第一分钟,X说,要有数列,于是便给定了一个正整数数列.第二分钟,L说,要能修改,于是便有了对一段数中每个数都开平方(下取整)的操作.第三分钟,k说,要能查询,于是便有了求一段数的和的操作.第四分钟,彩虹喵说,要是noip难度,于是便有了数据范围.第五分钟,诗人说,要有韵律,于