题目:https://www.luogu.org/problemnew/show/P4145

区间开平方,可以发现其实开几次就变成1,不需要开了,所以标记一下,每次只去开需要开的地方;

原来写的并查集跳过1或0,然而WA...其实是没有记录原数组的值,因为树状数组存的是修改量;

(如果a数组<原数组>开int会RE!)

改成线段树,本来想着是这一段区间和只要小于等于其长度就可以跳过了,然而仔细想想完全不是,应为可能有多个0什么的;

所以直接开bool数组标记一下就好了;

不需要pushdown,直接去修改或是跳过。

并查集:

#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
typedef long long ll;
int const MAXN=;
int n,m,a[MAXN],fa[MAXN];
ll f[MAXN];
int find(int x)
{
if(x==fa[x])return x;
return fa[x]=find(fa[x]);
}
void add(int x,ll y)
{
for(;x<=n;x+=(x&-x))
f[x]+=y;
}
void update(int x)
{
int tmp=a[x];
a[x]=sqrt(a[x]);
if(a[x]==||a[x]==)fa[x]=find(x+);
add(x,a[x]-tmp);
// for(;x<=n;x+=(x&-x))
// f[x]-=tmp,f[x]+=a[x];
}
ll query(int x)
{
// for(int i=1;i<=n;i++)
// printf("%d ",a[i]);
// printf("\n");
ll sum=;
for(;x;x-=(x&-x))
sum+=f[x];
return sum;
}
int main()
{
scanf("%d",&n);
for(int i=;i<=n;i++)
{
scanf("%d",&a[i]);
fa[i]=i;
add(i,a[i]);
}
// for(int i=1;i<=n;i++)
// printf("%lld ",f[i]);
// printf("\n");
fa[n+]=n+;
scanf("%d",&m);
while(m--)
{
int t,l,r;
scanf("%d%d%d",&t,&l,&r);
if(l>r)swap(l,r);
if(t==)
{
int x=find(l);
while(x<=r)
{
update(x);
x=find(x+);
// cout<<x<<endl;
}
}
if(t==)
{
ll s1=,s2=;
if(l-)s1=query(l-);
s2=query(r);
// printf("s1=%lld s2=%lld\n",s1,s2);
printf("%lld\n",s2-s1);
}
}
return ;
}

代码如下:

#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
typedef long long ll;
int const MAXN=;
int n,m;
ll tr[MAXN<<],a[MAXN];
bool tg[MAXN<<];
void pushup(int nw)
{
tr[nw]=tr[nw<<]+tr[nw<<|];
tg[nw]=(tg[nw<<]&&tg[nw<<|]);
}
//void pushdown(int l,int r,int nw)
//{
// if(l==r)
// {
// tr[nw]=sqrt(tr[nw]);
// return;
// }
// while(lz[nw])
// {
// if(tr[nw]<=r-l+1)
// {
// lz[nw]=0;
// break;
// }
// int mid=((l+r)>>1);
// if(tr[nw<<1]>mid-l+1)pushdown(l,mid,nw<<1);
// if(tr[nw<<1|1]>r-mid)pushdown(mid+1,r,nw<<1|1);
// pushup(nw);
// lz[nw]--;
// }
//}
void update(int l,int r,int L,int R,int nw)
{
if(tg[nw])return;
if(l==r)
{
tr[nw]=(ll)sqrt(tr[nw]);
if(tr[nw]==||tr[nw]==)tg[nw]=;
return;
}
int mid=((l+r)>>);
if(mid>=L)update(l,mid,L,R,nw<<);
if(mid<R)update(mid+,r,L,R,nw<<|);
pushup(nw);
}
ll query(int l,int r,int L,int R,int nw)
{
// for(int i=1;i<=n;i++)
// printf("%d ",a[i]);
// printf("\n");
ll sum=;
if(l>=L&&r<=R)
{
// pushdown(l,r,nw);
return tr[nw];
}
int mid=((l+r)>>);
if(mid>=L)sum+=query(l,mid,L,R,nw<<);
if(mid<R)sum+=query(mid+,r,L,R,nw<<|);
return sum;
}
void build(int l,int r,int nw)
{
if(l==r)
{
tr[nw]=a[l];
if(a[l]==||a[l]==)tg[nw]=;
return;
}
int mid=((l+r)>>);
build(l,mid,nw<<);
build(mid+,r,nw<<|);
pushup(nw);
}
int main()
{
scanf("%d",&n);
for(int i=;i<=n;i++)
scanf("%lld",&a[i]);
scanf("%d",&m);
build(,n,);
while(m--)
{
int d,x,y;
scanf("%d%d%d",&d,&x,&y);
if(x>y)swap(x,y);
if(d==)update(,n,x,y,);
if(d==)printf("%lld\n",query(,n,x,y,));
}
return ;
}

洛谷P4145上帝造题的七分钟——区间修改的更多相关文章

  1. 洛谷P4145 上帝造题的七分钟2/花神游历各国 [树状数组,并查集]

    题目传送门 题目背景 XLk觉得<上帝造题的七分钟>不太过瘾,于是有了第二部. 题目描述 "第一分钟,X说,要有数列,于是便给定了一个正整数数列. 第二分钟,L说,要能修改,于是 ...

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

    题目背景 XLk觉得<上帝造题的七分钟>不太过瘾,于是有了第二部. 题目描述 "第一分钟,X说,要有数列,于是便给定了一个正整数数列. 第二分钟,L说,要能修改,于是便有了对一段 ...

  3. 洛谷P4145 上帝造题的七分钟2 / 花神游历各国(重题:洛谷SP2713 GSS4 - Can you answer these queries IV)

    题目背景 XLk觉得<上帝造题的七分钟>不太过瘾,于是有了第二部. 题目描述 "第一分钟,X说,要有数列,于是便给定了一个正整数数列. 第二分钟,L说,要能修改,于是便有了对一段 ...

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

    洛谷 这题就是区间开根号,区间求和.我们可以分块做. 我们记布尔数组vis[i]表示第i块中元素是否全部为1. 因为显然当一个块中元素全部为1时,并不需要对它进行根号操作. 我们每个块暴力开根号,因为 ...

  5. 洛谷 P4514 上帝造题的七分钟 解题报告

    P4514 上帝造题的七分钟 题目背景 裸体(裸题)就意味着身体(神题). 题目描述 "第一分钟,X说,要有矩阵,于是便有了一个里面写满了\(0\)的\(n \times m\)矩阵. 第二 ...

  6. 洛谷P4514 上帝造题的七分钟

    P4514 上帝造题的七分钟 题目背景 裸体就意味着身体. 题目描述 "第一分钟,X说,要有矩阵,于是便有了一个里面写满了000的n×mn×mn×m矩阵. 第二分钟,L说,要能修改,于是便有 ...

  7. 洛谷P4145 上帝造题的⑦minutes ②

    又是线段树. 区间开平方求和,套路题. 如果开到了1就不用再开下去了,否则直接到底. 记得 l > r 时交换 l r #include <cstdio> #include < ...

  8. P4145 上帝造题的七分钟2

    题目描述 "第一分钟,X说,要有数列,于是便给定了一个正整数数列. 第二分钟,L说,要能修改,于是便有了对一段数中每个数都开平方(下取整)的操作. 第三分钟,k说,要能查询,于是便有了求一段 ...

  9. 【题解】 Luogu P4145 上帝造题的七分钟2 / 花神游历各国

    原题传送门 这道题实际和GSS4是一样的,只是输入方式有点区别 GSS4传送门 这道题暴力就能过qaq(这里暴力指线段树) 数据比较水 开方修改在线段树中枚举叶节点sqrt 查询区间和线段树基本操作 ...

随机推荐

  1. java 发送微信客服消息

    package com.baosight.wechat.service; import net.sf.json.JSONObject; import org.apache.commons.httpcl ...

  2. 修改 本地 IP 及 正则表达式 test exec match 的区别

    修改 IP 1.打开 "打开网络和共享中心" 2.打开 "更改适配器设置" 3.打开 "本地连接" 属性 4.修改 "协议版本 4 ...

  3. LeetCode – Copy List with Random Pointer

    A linked list is given such that each node contains an additional random pointer which could point t ...

  4. mysql 加密解密函数

    http://blog.csdn.net/wh62592855/article/details/6777753 mysql下的加密函数有如下几个 PASSWORD():创建一个经过加密的密码字符串,适 ...

  5. php empty、isset、is_null区别

    有关 PHP 的 empty(),isset() 还有 is_null() 这三个函数的用法讨论得已经很多了,而且很多资料也未必能说得很清楚.这里再重复一次,但不是从概念去说,直接用程序例子来说话,应 ...

  6. AngularJS 实现 双击排序

    关键代码:html <th class="col-md-3"><a href="" ng-click="desc('2',la=!l ...

  7. Jquery 插件 实例

    先说明下应用场景,通过可配项的配置和默认项覆盖,获取指定的需求数据,填充到指定的位置(两个指定其实都是可配的) (function($) { $.fn.extend({ getOneNews: fun ...

  8. 认识Gulp

    gulp详细入门教程:http://www.ydcss.com/archives/18 安装gulp 前提:已经安装node.js.npm $ npm install gulp --save-dev ...

  9. .NET 4.0 WCF WebConfig aspNetCompatibilityEnabled 属性

    近来被一个问题困扰了好久,好好的一个WCF后台服务,在发布机器上可用.在自己机器上没法跑起来. 一直提示兼容性问题,后来在网上找来解决方案,但问题依旧.没办法又从客户的服务器上重新把配置内容 拿下来审 ...

  10. java线程中断[interrupt()函数] (转载)

    一个正常的线程中断: 从运行到真正的结束,应该有三个阶段: 正常运行. 处理结束前的工作,也就是准备结束. 结束退出. Java曾经提供过抢占式限制中断,但问题多多,例如的Thread.stop.另一 ...