1. 程式人生 > >[BZOJ3211]花神遊歷各國&&[BZOJ3038] 上帝造題的七分鐘2 樹狀數組+並查集

[BZOJ3211]花神遊歷各國&&[BZOJ3038] 上帝造題的七分鐘2 樹狀數組+並查集

style mat change desc lap class poj ios 分享

3211: 花神遊歷各國

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

Description

技術分享

Input

技術分享

Output

每次x=1時,每行一個整數,表示這次旅行的開心度

Sample Input

4

1 100 5 5

5

1 1 2

2 1 2

1 1 2

2 2 3

1 1 4

Sample Output

101

11

11

HINT

對於100%的數據, n ≤ 100000,m≤200000 ,data[i]非負且小於10^9


Source

SPOJ2713 gss4 數據已加強

由於是開方,所以每個數的開放次數不超過logn次,用樹狀數組維護前綴和,對於修改操作變為單點修改。

用並查集維護當前節點之前的最近的一個非1節點。

復雜度o(nlog2n)

技術分享
 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

[BZOJ3211]花神遊歷各國&&[BZOJ3038] 上帝造題的七分鐘2 樹狀數組+並查集