BZOJ3211 花神游历各国 线段树+并查集
来源:互联网 发布:.cn域名可以过户吗? 编辑:程序博客网 时间:2024/06/05 01:02
BZOJ3211 花神游历各国 线段树+并查集
Description
维护区间和,支持区间开根。
Input
第一行一个n表示序列有n个数
第二行n个数表示原始序列的值
第三行一个m表示m个操作。
第四行到最后为m个操作,
每行3个数,x,l,r。
当x=1时,表示求
当x=2时,表示对[l,r]开根,向下取整。
Output
对应询问输出答案。
Sample Input
41 100 5 551 1 22 1 21 1 22 2 31 1 4
Sample Output
1011111
HINT
对于100%的数据, n ≤ 100000,m≤200000 ,data[i]非负且小于10^9
题解
当然,区间开根无法合并,所以,我们只能开根到点。可是这样搞会超时,得想办法优化。
我们发现,再int范围内,一个数最多开6次左右。所以经过一定量的开根,序列中会有相当一部分为1,而1的根有为1,可以不用理会。所以我们得想办法把这些无用功去掉。
可以用类似并查集的思想,用一个数组记录一个数下一位不为1的数,每次开根跳着开,开到一就更新这个数组即可。
#include <cstdio>#include <iostream>#include <cmath>#include <stack>#include <algorithm>#include <cstring>#include <climits>#define MAXN 100000+10#define LL long longusing namespace std;LL n,m,a[MAXN],num[MAXN<<2],sit[MAXN];int fa[MAXN];int find(int x){ if(fa[x]!=x) fa[x]=find(fa[x]); return fa[x];}void build(int rt,int l,int r){ if(l==r) { num[rt]=a[l]; sit[l]=rt; return ; } int m=(l+r)>>1; build(rt<<1,l,m); build(rt<<1|1,m+1,r); num[rt]=num[rt<<1]+num[rt<<1|1];}void update(int x,int l,int r,int rt){ if(l==r&&l==x) { num[rt]=sqrt(num[rt]); return; } int m=(l+r)>>1; if(x<=m) update(x,l,m,rt<<1); else if(x>m) update(x,m+1,r,rt<<1|1); num[rt]=num[rt<<1]+num[rt<<1|1];}LL query(int L,int R,int l,int r,int rt){ if(L<=l&&r<=R) return num[rt]; int m=(l+r)>>1;LL ans=0; if(L<=m) ans+=query(L,R,l,m,rt<<1); if(R>m) ans+=query(L,R,m+1,r,rt<<1|1); return ans;}int main(){ scanf("%lld",&n); for(int i=1;i<=n;i++) { scanf("%lld",&a[i]); fa[i]=i; } fa[n+1]=n+1; build(1,1,n); scanf("%lld",&m); for(int i=1;i<=m;i++) { int o,a,b; scanf("%d%d%d",&o,&a,&b); if(a>b) swap(a,b); if(o==2) { for(int j=find(a-1)+1;j<=find(b);) { update(j,1,n,1); if(num[sit[j]]==1||num[sit[j]]==0) fa[j-1]=j; j=find(j)+1; } }else printf("%lld\n",query(a,b,1,n,1)); } return 0;}
0 0
- 【bzoj3211】【花神游历各国】【线段树+并查集】
- BZOJ3211 花神游历各国 线段树+并查集
- [BZOJ3211]花神游历各国-树状数组-并查集
- BZOJ3211 花神游历各国 【树状数组 + 并查集】
- bzoj3211.花神游历各国(线段树)
- 花神游历各国 bzoj3211 线段树
- bzoj3211 花神游历各国 线段树
- [bzoj3211]花神游历各国 线段树
- bzoj3211 花神游历各国(线段树)
- bzoj3211花神游历各国 线段树
- BZOJ3211[花神游历各国]--线段树
- bzoj3211 花神游历各国 ( 线段树 )
- [BZOJ3211]花神游历各国(线段树)
- [BZOJ3211]花神游历各国 势能线段树
- BZOJ3211 花神游历各国(线段树,区间开根号)
- 【BZOJ3211】花神游历各国 树状数组 并查集 均摊分析
- BZOJ3211 花神游历各国(树状数组+并查集)
- 【bzoj3211】花神游历各国
- [LeetCode] Sum of Left Leaves 左叶子节点的和
- java中Scanner
- A003-算法-滑动窗口队列(未测试)
- windows tcp buffer size 调研
- 3、类和接口
- BZOJ3211 花神游历各国 线段树+并查集
- <模型汇总-5>开山鼻祖-深度信念网络DBN
- Java多线程编程总结
- <转载>名言
- 检验输入的mac是否是符合mac形式
- 将数据封装为Json数据格式
- 5、方法
- Gym
- DELL服务器r231011安装操作系统