BZOJ3211 花神游历各国
2015-07-17 17:50
330 查看
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(logAi)次就会变成0或1,所以每次暴力修改一个单点可行。
但我们怎么找到区间中所有不是0和1的点呢?用并查集维护每个位置下一个合法的位置,细节见代码。
#include<cstdio> #include<cstring> #include<algorithm> #include<cctype> #include<cmath> #define rep(s,t) for(int i=s;i<=t;i++) #define ren for(int i=first[x];i!=-1;i=next[i]) using namespace std; typedef long long ll; inline ll read() { ll x=0,f=1;char c=getchar(); for(;!isdigit(c);c=getchar()) if(c=='-') f=-1; for(;isdigit(c);c=getchar()) x=x*10+c-'0'; return x*f; } const int maxn=100010; int n,fa[maxn],A[maxn]; inline int findset(int x) {return !fa[x]||x==fa[x]?x:fa[x]=findset(fa[x]);} ll c[maxn]; void add(int x,ll v) {for(;x<=n;x+=x&-x) c[x]+=v;} ll sum(int x) {ll ret=0;for(;x;x-=x&-x) ret+=c[x];return ret;} int main() { n=read(); rep(1,n) { add(i,A[i]=read()); if(A[i]<=1) fa[i]=i+1; } int q=read(); while(q--) { int t=read(),l=read(),r=read(); if(t==1) printf("%lld\n",sum(r)-sum(l-1)); else { for(int i=findset(l);i<=r;i=findset(i+1)) { int t=sqrt(A[i]); add(i,t-A[i]);A[i]=t; if(A[i]<=1) fa[i]=findset(i+1); } } } return 0; }
View Code
相关文章推荐
- JasperReport学习笔记(一)
- 关于自定义转场动画,我都告诉你
- js中window.onload 与 jquery中$(document.ready()) 测试
- 红牛v5 android cm12.1 分辨率修改
- SDI接口
- Java 多线程间的通信——wait及notify方法
- GRE写作必备句型
- 几个高效PHP加速器推荐
- Memcached深度分析
- Free Heap block xxxxxxxx modified at xxxxxxxx after it was freed
- C#下每次build自动版本号更新
- 动画特效三:搜索动画
- Java NIO 简单总结
- Caused by: android.content.res.Resources$NotFoundException: String resource ID #0x0
- 给views slideshow添加圆点counter
- 前端构建工具gulp入门教程(share)
- 通过邮件发送running process输出最后N行
- PAT 1095 Cars on Campus 模拟
- quartz的触发器CronTriggerBean 配置
- ARC 下内存泄露的那些点