BZOJ 3211: 花神游历各国/BZOJ 3038: 上帝造题的七分钟2 树状数组+并查集

来源:互联网 发布:ubuntu应用商店慢 编辑:程序博客网 时间:2024/05/16 01:23

3211: 花神游历各国

Time Limit: 5 Sec  Memory Limit: 128 MB
Submit: 3311  Solved: 1227
[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


今天alone_wolf又在讲线段树啦

作为例题之一我查了题解。。。

因为对于每个数最多O(nloglogn)次不会再改变(变成0 or 1)

所以。。一顿乱搞

哦,对了,不要忘记最后一个数会指向区间之外,做一下标记要不会死循环。。。

PS: 3038比较坑。。看看题。。鬼畜WA两发


#include<cmath>#include<ctime>#include<cstdio>#include<cstring>#include<cstdlib>#include<complex>#include<iostream>#include<algorithm>#include<iomanip>#include<vector>#include<string>#include<queue>#include<set>#include<map>using namespace std;typedef long long ll;inline ll read(){ll x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch<='9'&&ch>='0'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}return x*f;}const int N=100100;int n,fa[N];ll c[N],a[N];inline int find(int x){int t=x;while(t!=fa[t])t=fa[t];while(x!=fa[x])x=fa[x],fa[x]=t;return x;}inline void update(int x,ll val){for(;x<=n;x+=(x&-x))c[x]+=val;}inline void modify(int x,int y){for(int i=x;i<=y;i=find(i+1)){ll t=floor(sqrt(a[i]));update(i,t-a[i]);a[i]=t;if(a[i]<=1)fa[i]=find(i+1);}}inline void query(int x,int y){ll sum=0;for(;y;y-=(y&-y))sum+=c[y];for(;x;x-=(x&-x))sum-=c[x];printf("%lld\n",sum);}int main(){n=read();for(int i=1;i<=n;i++){a[i]=read(),fa[i]=i,update(i,a[i]);if(a[i]<=1)fa[i]=i+1;}fa[n+1]=n+1;int m=read();while(m--){int opt=read(),x=read(),y=read();if(x>y)swap(x,y);if(opt==1){query(x-1,y);}else {modify(x,y);}}return 0;}/*41 100 5 551 1 22 1 21 1 22 2 31 1 41011111*/


阅读全文
0 0