[平方根]
来源:互联网 发布:windows经典主题 编辑:程序博客网 时间:2024/04/28 08:32
题面:
观察发现,一个数最多被开平方根6次,6次以后就只能为1,可以不去处理
于是可以用线段树进行区间修改:
若待修改线段与当前线段重合,且这个区间里只有1,就可以不往下处理
否则就需要递归到最底部,进行直接修改
根据前面所说,一个数最多被处理6次,复杂度为O(6*nlogn)=O(nlogn)
当然,也可以用另一种方法:并查集+树状数组
因为1是无用的,所以从l~r修改时可以跳过一连串的1,这里很适合用并查集来处理
至于树状数组是用来快速统计区间加和的,复杂度O(nlogn)
#include<cstdio>#include<cmath>#include<cstdlib>#include<cstring>#define LL long long#define lowbit(x) ((x)&-(x))const int maxn=100005;int n,q,times,fa[maxn];LL a[maxn],tre[maxn];inline LL red(){ LL tot=0;char ch=getchar(); while (ch<'0'||'9'<ch) {if (ch==EOF) exit(0);ch=getchar();} while ('0'<=ch&&ch<='9') tot=tot*10+ch-48,ch=getchar(); return tot;}void ist(int i,LL x){ while (i<=n) tre[i]+=x, i+=lowbit(i);}LL qry(int i){ LL res(0); while (i) res+=tre[i], i-=lowbit(i); return res;}int getfa(int x){ if (fa[x]==x) return x; return fa[x]=getfa(fa[x]);}void work(int x){ LL aa=sqrt(a[x]); ist(x,aa-a[x]);a[x]=aa; if (aa==1) fa[x]=fa[x+1];}int main(){ freopen("sqrt.in","r",stdin); freopen("sqrt.out","w",stdout); while (n=red()){ printf("Case #%d:\n",++times); memset(tre,0,sizeof(tre)); for (int i=1;i<=n;i++){ a[i]=red();ist(i,a[i]); if (a[i]==1) fa[i]=i+1;else fa[i]=i; }fa[n+1]=n+1; q=red();int l,r; while (q--) if (red()) l=red(),r=red(),printf("%lld\n",qry(r)-qry(l-1));else{ l=red(),r=red(); for (int i=getfa(l);i<=r;i=getfa(i+1)) work(i); } putchar(10); } return 0;}
1 0
- 平方根
- [平方根]
- 平方根
- 求平方根
- 近似平方根
- 整数平方根
- 大数 平方根
- 迭代求平方根
- 求平方根
- 平方根程序
- 大数 平方根
- 求平方根
- 求平方根
- 平方根法
- 平方根法
- 求平方根或近似平方根
- 快速平方根(平方根倒数)算法
- 卡马克快速平方根
- Java Collections Framework概览
- 字节 输入输出流 byte
- Android之ContentProvider跨程序共享数据入门(笔记一)
- Ubuntu15安装Dock工具栏
- python数据持久存储:pickle模块的基本使用
- [平方根]
- Python 日期和时间
- bat批处理编程基本语法(1)
- react——JSX语法
- android中?号和@号的区别
- Kafka副本同步机制理解
- 机器学习,k近邻分类器,python,
- python中__getitem__, __setitem__, __delitem__的使用
- java数组学习