|BZOJ 3211|树状数组|并查集|花神游历各国

来源:互联网 发布:阿提拉全面战争知乎 编辑:程序博客网 时间:2024/06/05 03:35

BZOJ传送门
树状数组裸题,但是因为sqrt的速度很慢,所以我们在一个数为1或者为0就删掉它(用并查集维护)
ps:交题时注意文件声明部分要注释掉!坑死了

#include<cstdio>#include<cstring>#include<algorithm>#include<cmath>#include<iostream>#define ms(i,j) memset(i, j, sizeof i);#define ll long longusing namespace std;const int MAXN = 100000 + 5;ll a[MAXN], f[MAXN];int data[MAXN];int n,m;int lowbit(ll x) {return x&(-x);}int find(int x){    if (f[x]==x) return x;    else return f[x] = find(f[x]);}ll sum(int x){    ll ret = 0;    for (ll i=x;i>0;i-=lowbit(i))    {        ret += (ll)a[i];    }    return ret;}int update(int x, int c){    for (ll i=x;i<=n;i+=lowbit(i))    {        a[i] += c;    }}int main(){    //freopen("bzoj3211.in", "r", stdin); freopen("bzoj3211.out", "w", stdout);    scanf("%d\n", &n); ms(a, 0);    for (int i=1;i<=n+1;i++) f[i] = i;    for (int i=1;i<=n;i++)     {        scanf("%lld", &data[i]);        if (data[i]==1||data[i]==0) f[i] = find(i+1);        update(i, data[i]);     }    scanf("%d", &m);    for (int i=1;i<=m;i++)    {        int x, l, r;        scanf("%d%d%d", &x, &l, &r);        if (x==1) printf("%lld\n", sum(r)-sum(l-1)); else if (x==2)        {            for (int j=find(l);j<=r;j=find(j+1))            {                update(j, (ll)(sqrt(data[j]))-data[j]);                data[j] = (ll)(sqrt(data[j]));                if(data[j]==1)                {                    f[j] = find(j+1);                }            }        }    }    return 0;}
0 0
原创粉丝点击