洛谷P4145上帝造题的七分钟——区间修改
题目: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上帝造题的七分钟——区间修改的更多相关文章
- 洛谷P4145 上帝造题的七分钟2/花神游历各国 [树状数组,并查集]
题目传送门 题目背景 XLk觉得<上帝造题的七分钟>不太过瘾,于是有了第二部. 题目描述 "第一分钟,X说,要有数列,于是便给定了一个正整数数列. 第二分钟,L说,要能修改,于是 ...
- 洛谷P4145——上帝造题的七分钟2 / 花神游历各国
题目背景 XLk觉得<上帝造题的七分钟>不太过瘾,于是有了第二部. 题目描述 "第一分钟,X说,要有数列,于是便给定了一个正整数数列. 第二分钟,L说,要能修改,于是便有了对一段 ...
- 洛谷P4145 上帝造题的七分钟2 / 花神游历各国(重题:洛谷SP2713 GSS4 - Can you answer these queries IV)
题目背景 XLk觉得<上帝造题的七分钟>不太过瘾,于是有了第二部. 题目描述 "第一分钟,X说,要有数列,于是便给定了一个正整数数列. 第二分钟,L说,要能修改,于是便有了对一段 ...
- 洛谷 P4145 上帝造题的七分钟2 / 花神游历各国
洛谷 这题就是区间开根号,区间求和.我们可以分块做. 我们记布尔数组vis[i]表示第i块中元素是否全部为1. 因为显然当一个块中元素全部为1时,并不需要对它进行根号操作. 我们每个块暴力开根号,因为 ...
- 洛谷 P4514 上帝造题的七分钟 解题报告
P4514 上帝造题的七分钟 题目背景 裸体(裸题)就意味着身体(神题). 题目描述 "第一分钟,X说,要有矩阵,于是便有了一个里面写满了\(0\)的\(n \times m\)矩阵. 第二 ...
- 洛谷P4514 上帝造题的七分钟
P4514 上帝造题的七分钟 题目背景 裸体就意味着身体. 题目描述 "第一分钟,X说,要有矩阵,于是便有了一个里面写满了000的n×mn×mn×m矩阵. 第二分钟,L说,要能修改,于是便有 ...
- 洛谷P4145 上帝造题的⑦minutes ②
又是线段树. 区间开平方求和,套路题. 如果开到了1就不用再开下去了,否则直接到底. 记得 l > r 时交换 l r #include <cstdio> #include < ...
- P4145 上帝造题的七分钟2
题目描述 "第一分钟,X说,要有数列,于是便给定了一个正整数数列. 第二分钟,L说,要能修改,于是便有了对一段数中每个数都开平方(下取整)的操作. 第三分钟,k说,要能查询,于是便有了求一段 ...
- 【题解】 Luogu P4145 上帝造题的七分钟2 / 花神游历各国
原题传送门 这道题实际和GSS4是一样的,只是输入方式有点区别 GSS4传送门 这道题暴力就能过qaq(这里暴力指线段树) 数据比较水 开方修改在线段树中枚举叶节点sqrt 查询区间和线段树基本操作 ...
随机推荐
- windows下通过VNC图形化訪问Ubuntu桌面环境
要在windows下图形化訪问Ubuntu或其他Linux系统桌面环境有非常多方法.我比較喜欢的是使用VNC服务,须要在Ubuntu下安装vncserver和在windows下安装client訪问工具 ...
- GTK入门学习:布局练习之计算器
接下来,我们做一个布局练习.例如以下图: 我们用表格布局实现,表格布局參考坐标例如以下: 这里我们用到行编辑控件( GtkEntry ). 行编辑的创建: GtkWidget * gtk_entry_ ...
- [笔记] sed and awk
/ awk程序的典型示例是将数据转换成格式化的报表,当数据拥有某种结构时就能最好的体现awk的好处:可以使用awk脚本对数据的列重新排序,甚至可以将列变成行以及将行变成列:awk的功能将文本编辑的思想 ...
- canvas转盘抽奖的实现(二)
本篇是<canvas转盘抽奖的实现(一)>的另一种实现方法,主要通过css3的transform以及transition过渡来实现. // ' + r + '等奖'; } draw ...
- 用python模拟TCP3次握手连接及发送数据
源码如下: from scapy.all import * import logging logging.getLogger('scapy.runtime').setLevel(logging.ERR ...
- 04 http协议模拟登陆发帖
<?php require('./http.class.php'); $http = new Http('http://home.verycd.com/cp.php?ac=pm&op=s ...
- 九度OJ 1132:与7无关的数 (数字特性)
时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:1619 解决:1037 题目描述: 一个正整数,如果它能被7整除,或者它的十进制表示法中某个位数上的数字为7, 则称其为与7相关的数.现求所 ...
- The server must be started under an unprivileged user ID to prevent
mysql8 PostgreSQL [root@test local]# postgres -D /usr/local/pgsql/data"root" execution of ...
- ZeroMQ Distributed Messaging
ZeroMQ \zero-em-queue\, \ØMQ\: Ø Connect your code in any language, on any platform. Ø Carries mes ...
- C++正则表达式笔记之wregex
遍历所有匹配 #include <iostream> #include <regex> using namespace std; int main() { wstring ws ...