题目: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. jquery_ajax 入门实例

    序:本文通过几个小样例,简单介绍怎样使用jqueryAjax异步载入. 1. $(selector).load(url,[data],[callback]) :加载远程HTML文件代码并插入DOM中. ...

  2. 蜗牛—Android基础之button监听器

    XML文件中有一个textView 和 一个button. <LinearLayout xmlns:android="http://schemas.android.com/apk/re ...

  3. Something about cache

    http://www.tyut.edu.cn/kecheng1/2008/site04/courseware/chapter5/5.5.htm 5.5 高速缓冲存储器cache 随着CPU时钟速率的不 ...

  4. 【课程笔记】比特币和数字货币技术[Bitcoin and Cryptocurrency Technologies] week1

    源地址(可能要FQ):https://www.coursera.org/learn/cryptocurrency/home/welcome 1.1 Cryptographic Hash Functio ...

  5. EasyPusher直播推送中用到的缓冲区设计和丢帧原理

    问题描述 我们在开发直播过程中,会需要用到直播推送端,推送端将直播的音视频数据推送到流媒体服务器或者cdn,再由流媒体服务器/CDN进行视频的转发和分发,提供给客户端进行观看.由于直播推送端会存在于各 ...

  6. poi 处理excel 小数问题 整数不保留小数位 整数多.0

    读取的单元格为 hssfCell ,传入下面我提供的方法处理默认poi返回的为DOUBLE,所有先转为Long判断下,再进行返回: private String getValue(Cell hssfC ...

  7. You're trying to decode an invalid JSON String JSON返回有解析问题

    SpringMVC架构的web程序,通常用map返回消息在浏览器中显示,但是实际中报下列错误“”You're trying to decode an invalid JSON String“返回的字符 ...

  8. struts2的输入检验

    一.输入校验简介 一个健壮的Web应用程序必须确保用户输入是合法的.比如在注册用户的时候,将用处注册信息保存到数据库之前一般我们会判断用户输入的密码长度是否过短,或者用户的email地址格式是否正确. ...

  9. 九度OJ 1090:路径打印 (树、DFS)

    时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:1704 解决:314 题目描述: 给你一串路径,譬如: a\b\c a\d\e b\cst d\ 你把这些路径中蕴含的目录结构给画出来,子目 ...

  10. curl is a tool to transfer data from or to a server curl POST

    https://curl.haxx.se/docs/manpage.html curl is a tool to transfer data from or to a server, using on ...