# [BZOJ3211]花神游历各国&&[BZOJ3038] 上帝造题的七分钟2 树状数组+并查集

## 3211: 花神游历各国

Time Limit: 5 Sec  Memory Limit: 128 MB
Submit: 4057  Solved: 1480
[Submit][Status][Discuss]

4

1 100 5 5

5

1 1 2

2 1 2

1 1 2

2 2 3

1 1 4

101

11

11

## Source

SPOJ2713 gss4 数据已加强

 1 #include<iostream>
2 #include<cstring>
3 #include<cstdio>
4 #include<cstdlib>
5 #include<cmath>
6 #include<algorithm>
7 using namespace std;
8 int read() {
9     int x=0;char ch=getchar();
10     while(!isdigit(ch)) ch=getchar();
11     while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();}
12     return x;
13 }
14 int n,m;
15 long long sum[100005];
16 long long a[100005];
17 int fa[100005];
18 int find(int x){return fa[x]==x?fa[x]:fa[x]=find(fa[x]);}
19 int lowbit(int x){return x&(-x);}
20 void add(int x,long long val) {
21     for(int i=x;i<=n;i+=lowbit(i)) sum[i]+=val;
22 }
23 void change(int x,long long val) {
24     for(int i=x;i<=n;i+=lowbit(i)) sum[i]=sum[i]-val+(long long)sqrt(val);
25 }
26 long long query(int x) {
27     long long ans=0;
28     for(int i=x;i>0;i-=lowbit(i)) ans+=sum[i];
29     return ans;
30 }
31 int main() {
32     n=read();
33     for(int i=1;i<=n;i++) {a[i]=read();add(i,a[i]);}
34     for(int i=1;i<=n;i++) fa[i]=i;
35     m=read();
36     while(m--) {
37         int x=read(),l=read(),r=read();
38         if(x==2) {
39             int now=find(r);
40             while(now>=l) {
41                 change(now,a[now]);
42                 a[now]=sqrt(a[now]);
43                 if(a[now]<=1) fa[now]=find(fa[now-1]);
44                 now=find(fa[now-1]);
45             }
46         }
47         else {
48             printf("%lld\n",query(r)-query(l-1));
49         }
50     }
51     return 0;
52 }
View Code

posted @ 2017-11-07 15:26  wls001  阅读(95)  评论(0编辑  收藏  举报