【bzoj3211】花神游历各国
2016-08-11 15:27
274 查看
首先,单点修改求区间和可以用树状数组实现
因为开平方很耗时间,所以在这个方面可以优化
我们知道,开平方开几次之后数字就会等于1
所以,用数组记录下一个应该开的数,每次直接跳到下一个不是1的数字进行开平方,至于这个数组,可以用并查集维护。
因为开平方很耗时间,所以在这个方面可以优化
我们知道,开平方开几次之后数字就会等于1
所以,用数组记录下一个应该开的数,每次直接跳到下一个不是1的数字进行开平方,至于这个数组,可以用并查集维护。
#include<algorithm> #include<iostream> #include<cstdlib> #include<cstring> #include<cstdio> #include<cmath> using namespace std; typedef long long LL; #define lowbit(x) (x&(-x)) #define N 100010 int n,m; int ask,l,r,t; int f ,a ; LL c ; inline int getint() { int x=0,f=1; char ch=getchar(); while (ch>'9' || ch<'0') { if (ch=='-') f=-1; ch=getchar(); } while (ch>='0' && ch<='9') { x=x*10+ch-'0'; ch=getchar(); } return x*f; } inline int find(int x) { return x==f[x] ? x : f[x]=find(f[x]); } inline void add(int x,int d) { while (x<=n) c[x]+=d,x+=lowbit(x); } inline LL query(int x) { LL res(0); while (x) res+=c[x],x-=lowbit(x); return res; } int main() { n=getint(); for (int i=1;i<=n;i++) { a[i]=getint(); f[i]=i; add(i,a[i]); } f[n+1]=n+1; m=getint(); while (m--) { ask=getint(),l=getint(),r=getint(); if (ask==1) printf("%lld\n",query(r)-query(l-1)); else for (int i=l;i<=r;add(i,(t=(int)sqrt(a[i]))-a[i]),a[i]=t,f[i]=(a[i]<=1) ? i+1 : i,i=(find(i)==i ? i+1 : f[i])); } return 0; }
相关文章推荐
- BZOJ 3211 花神游历各国
- [BZOJ3211][SPOJ2713][线段树]GSS 4(花神游历各国)[一般题]
- bzoj3211花神游历各国 线段树
- BZOJ-3211花神游历各国 并查集+树状数组
- BZOJ 3211 花神游历各国 树状数组+并查集
- BZOJ3211 花神游历各国 线段树+并查集
- 【bzoj3211】花神游历各国
- bzoj-3211 花神游历各国
- BZOJ-3211花神游历各国 并查集+树状数组
- BZOJ 3211: 花神游历各国 线段树区间开根
- bzoj3211花神游历各国 线段树
- BZOJ 3211: 花神游历各国(势能分析线段树)
- BZOJ3211 花神游历各国
- BZOJ 3211: 花神游历各国( 线段树 )
- bzoj3211: 花神游历各国&&3038: 上帝造题的七分钟2
- [BZOJ3211]花神游历各国(线段树+区间开根)
- bzoj 3211: 花神游历各国
- [bzoj3211][并查集][树状数组]花神游历各国
- BZOJ 3211 花神游历各国 树状数组+并查集
- [BZOJ3211]花神游历各国