【bzoj3211】【花神游历各国】【线段树+并查集】
2015-09-26 14:31
197 查看
Description
Input
Output
每次x=1时,每行一个整数,表示这次旅行的开心度Sample Input
41 100 5 5
5
1 1 2
2 1 2
1 1 2
2 2 3
1 1 4
Sample Output
10111
11
HINT
对于100%的数据, n ≤ 100000,m≤200000 ,data[i]非负且小于10^9题解:可以发现一个数最多开log次根就会变成0或1.
然后一个数如果还没变成0或1,我们就暴力修改
如果已经变成0或1,我们就用并查集维护一下0,1块。
这样每个数只会被访问log次,
代码:
#include<iostream> #include<cstdio> #include<cmath> #define N 100010 using namespace std; long long t[N*4]; int a ; int n,m,l,r,fa ,kind,tt; inline int find(int x){if (x!=fa[x]) fa[x]=find(fa[x]);return fa[x];} inline int read(){ int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } inline void change(int k,int l,int r,int p,long long v){ int mid=(l+r)>>1; if (l==r){t[k]=a[p];return;} if (p<=mid) change(k<<1,l,mid,p,v); else change(k<<1|1,mid+1,r,p,v); t[k]=t[k<<1]+t[k<<1|1]; } inline long long query(int k,int l,int r,int ll,int rr){ int mid=(l+r)>>1;long long ans(0); if (ll<=l&&r<=rr) return t[k]; if (ll<=mid) ans+=query(k<<1,l,mid,ll,rr); if (mid<rr) ans+=query(k<<1|1,mid+1,r,ll,rr); return ans; } int main(){ n=read(); for (int i=1;i<=n;i++) {a[i]=read();change(1,1,n,i,(long long)a[i]);} for (int i=1;i<=n+1;i++) fa[i]=i; m=read(); for (int i=1;i<=m;i++){ kind=read();l=read();r=read();if (l>r) swap(l,r); if (kind==1) printf("%lld\n",query(1,1,n,l,r)); if (kind==2){ tt=find(l); while (tt<=r){ a[tt]=sqrt(a[tt]); change(1,1,n,tt,(long long)a[tt]); if (a[tt]==1||a[tt]==0) fa[tt]=tt+1; if (find(tt)!=tt) tt=find(tt);else tt++; } } } }
相关文章推荐
- 黑马程序员---Java基础加强---代理
- 输出多行字符的一个简单JAVA小程序
- ViewPager实现引导页
- 如何修改SpriteBuilder中的按钮禁用启用状态
- 如何修改SpriteBuilder中的按钮禁用启用状态
- A Sweet Journey
- 如何修改SpriteBuilder中的按钮禁用启用状态
- handlebars学习笔记
- myeclipse项目转maven项目
- iOS开发:集合视图 UICollectionView
- android开发之android:process属性_application中onCreate执行多次
- fzu 2150 Fire Game 【身手BFS】
- 左右HttpClient上传的方法来解决中国的乱码
- Eclipse常用插件
- 黑盒测试案例分析之等价类划分
- REST WebService
- vector中迭代器的用法
- PAT1044 火星数字
- AsyncTask的缺陷
- iOS事件捕捉与传递,响应者链