【算法】线段树||树状数组&&并查集

【题解】修改必须暴力单点修改,然后利用标记区间查询。

优化:一个数经过不断开方很快就会变成1,所以维护区间最大值。

修改时访问到的子树最大值<=1时,该区间就不必修改。

#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
const int maxn=;
struct treess{int k,l,r;long long maxs,sum;}t[maxn*];
int n,m;long long a[maxn];
void build(int k,int l,int r)
{
t[k].l=l;t[k].r=r;
if(l==r)t[k].maxs=t[k].sum=a[l];
else
{
int mid=(l+r)>>;
build(k<<,l,mid);
build(k<<|,mid+,r);
t[k].maxs=max(t[k<<].maxs,t[k<<|].maxs);//printf("k=%d maxs=%d",k,t[k].maxs);
t[k].sum=t[k<<].sum+t[k<<|].sum;
}
}
void update(int k,int l,int r)
{
int left=t[k].l,right=t[k].r;
if(t[k].maxs<=)return;
if(left==right)a[left]=floor(sqrt(a[left])),t[k].maxs=t[k].sum=a[left];
else
{
int mid=(left+right)>>;
if(l<=mid)update(k<<,l,r);
if(r>mid)update(k<<|,l,r);
t[k].maxs=max(t[k<<].maxs,t[k<<|].maxs);
t[k].sum=t[k<<].sum+t[k<<|].sum;
}
}
long long ask(int k,int l,int r)
{
int left=t[k].l,right=t[k].r;
if(l<=left&&right<=r)return t[k].sum;
int mid=(left+right)>>;long long ans=;
if(l<=mid)ans=ask(k<<,l,r);
if(r>mid)ans+=ask(k<<|,l,r);
return ans;
}
int main()
{
scanf("%d",&n);
for(int i=;i<=n;i++)scanf("%lld",&a[i]);
scanf("%d",&m);
build(,,n);
for(int i=;i<=m;i++)
{
int k,l,r;
scanf("%d%d%d",&k,&l,&r);
if(l>r)swap(l,r);
if(k==)update(,l,r);
else printf("%lld\n",ask(,l,r));
}
return ;
}

并查集将ai=1的节点并起来,也就是fa[i]表示i后第一个ai≠1的节点,然后用树状数组单点修改区间维护前缀和。

带删除的寻数问题,都可以用类似的并查集套路解决。

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#define lowbit(x) x&(-x)
#define ll long long
using namespace std;
const ll maxn=;
ll n,m,fa[maxn],a[maxn];
long long c[maxn]; void modify(ll x,ll k){for(ll i=x;i<=n;i+=lowbit(i))c[i]+=k;}
long long ask(ll x){long long as=;for(ll i=x;i>=;i-=lowbit(i))as+=c[i];return as;}
ll find(ll x){return fa[x]==x?x:fa[x]=find(fa[x]);}
int main(){
scanf("%lld",&n);
for(ll i=;i<=n;i++)scanf("%lld",&a[i]),modify(i,a[i]);
for(ll i=;i<=n+;i++)fa[i]=i;
scanf("%lld",&m);
for(ll i=;i<=m;i++){
ll k,l,r;
scanf("%lld%lld%lld",&k,&l,&r);
if(l>r)swap(l,r);
if(k==)printf("%lld\n",ask(r)-ask(l-));
else{
for(ll j=l;j<=r;j++){
j=find(j);
if(j<=r){
modify(j,(ll)sqrt(a[j])-a[j]);
a[j]=(ll)sqrt(a[j]);
if(a[j]<=)fa[j]=find(j+);
}
}
}
}
return ;
}

【BZOJ】3038: 上帝造题的七分钟2 && 3211: 花神游历各国的更多相关文章

  1. 题解【luogu4145 上帝造题的七分钟2(花神游历各国)】

    题目大意: 一个序列,支持区间开方与求和操作. 算法:线段树实现开方修改与区间求和 分析: 显然,这道题的求和操作可以用线段树来维护 但是如何来实现区间开方呢 大家有没有这样的经历:玩计算器的时候,把 ...

  2. 题解【luoguP4145 上帝造题的七分钟2(花神游历各国)】

    题目链接 题解 题目大意: 一个序列,支持区间开方与求和操作. 算法:线段树实现开方修改与区间求和 分析: 显然,这道题的求和操作可以用线段树来维护 但是如何来实现区间开方呢 大家有没有这样的经历:玩 ...

  3. 【线段树】bzoj3038 上帝造题的七分钟2 / bzoj3211 花神游历各国

    暴力修改,记录一段是否全部为1或0,若全是了,则不再修改. 注意3211一定要判是否为0,否则会T得惨无人道. #include<cstdio> #include<cmath> ...

  4. BZOJ 3038: 上帝造题的七分钟2

    3038: 上帝造题的七分钟2 Description XLk觉得<上帝造题的七分钟>不太过瘾,于是有了第二部. "第一分钟,X说,要有数列,于是便给定了一个正整数数列. 第二分 ...

  5. BZOJ 3038: 上帝造题的七分钟2【线段树区间开方问题】

    3038: 上帝造题的七分钟2 Time Limit: 3 Sec  Memory Limit: 128 MBSubmit: 1469  Solved: 631[Submit][Status][Dis ...

  6. bzoj 3038: 上帝造题的七分钟2 线段树||hdu 4027

    3038: 上帝造题的七分钟2 Time Limit: 3 Sec  Memory Limit: 128 MBSubmit: 1066  Solved: 476[Submit][Status][Dis ...

  7. BZOJ 3038: 上帝造题的七分钟2 / BZOJ 3211: 花神游历各国 (线段树区间开平方)

    题意 给出一些数,有两种操作.(1)将区间内每一个数开方(2)查询每一段区间的和 分析 普通的线段树保留修改+开方优化.可以知道当一个数为0或1时,无论开方几次,答案仍然相同.所以设置flag=1变表 ...

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

    题解:同 BZOJ 3211 花神游历各国,需要注意的是需要开long long,还有左右节点需要注意一下. #include <cstdio> #include <cmath> ...

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

    题目大意:一个序列,有两种操作.1.将一段数中的每个数开根号.2.查询一段数的和. 思路:和3211是一个题,有兴趣的能够看看我的那篇博客. CODE: #include <cmath> ...

随机推荐

  1. xml解析----java中4中xml解析方法(转载)

    转载:https://www.cnblogs.com/longqingyang/p/5577937.html 描述 XML是一种通用的数据交换格式,它的平台无关性.语言无关性.系统无关性.给数据集成与 ...

  2. C# 创建Excel或需不安装Office

    第一种.Aspose.Cells.dll //如果需要饶过office Excel那么就看我最后的实现方法吧~! //我最后的实现是使用的第三方Aspose.Cells.dll //具了解这个dll一 ...

  3. Python实现XML的操作

    本文从以下两个方面, 用Python实现XML的操作: 一. minidom写入XML示例1 二. minidom写入XML示例2 三. ElementTree写入/修改示例 四. ElementTr ...

  4. 【Linux】- Ubutnu UFW防火墙的简单设置

    ufw是一个主机端的iptables类防火墙配置工具,比较容易上手.一般桌面应用使用ufw已经可以满足要求了. 安装方法 sudo apt-get install ufw 使用方法 1.启用: sud ...

  5. SQL SERVER技术内幕之7 透视与逆透视

    1.透视转换 透视数据(pivoting)是一种把数据从行的状态旋转为列的状态的处理,在这个过程中可能须要对值进行聚合. 每个透视转换将涉及三个逻辑处理阶段,每个阶段都有相关的元素:分组阶段处理相关的 ...

  6. C#中WVVM的使用

    学习WVVM模式,设计一个简单的菜单显示和选择时显示个数的一个例子. 最终效果: 所建文件结构如下: MenuModel:菜品属性-名称和价格 using System; using System.C ...

  7. poj1065-Wooden Sticks

    题目 有很多小木棍需要机器处理.每个小木棍有重量和长度两个属性.不断把小木棍放入机器中,如果小木棍\(a\)放完后放入小木棍\(b\),那么如果\(a.weight<=b.weight\ and ...

  8. 【bzoj2272】[Usaco2011 Feb]Cowlphabet 奶牛文字 dp

    题目描述 Like all bovines, Farmer John's cows speak the peculiar 'Cow'language. Like so many languages, ...

  9. 【题解】CF#1012 C-Hill

    感觉这题的状态还是比较明显的.设置状态 \(f[i][j][0/1]\) 表示dp到第 \(i\) 个位置,前面(包括这里)已经出现了 \(j\) 个山峰,当前位置是不是山峰即可 dp.这样的状态有一 ...

  10. Android 解决setRequestedOrientation之后手机屏幕的旋转不触发onConfigurationChanged方法

    最近在做播放器的时候遇到一个问题,在屏幕方向改变之后需要切换播放器全屏/非全屏的时候,在重写了onConfigurationChanged方法并在manifest.xml配置文件中添加 android ...