zoukankan      html  css  js  c++  java
  • 花神游历各国 题解(小清新线段树/树状数组+并查集)

    题面

    众所周知,这是一道小清新线段树

    然而可以用树状数组水过去且跑得飞快

    看到区间开方第一反应肯定是线段树懒标记区间修改之类的,但是这个东西似乎确凿不可维护

    所以考虑暴力循环单点修改->T飞

    于是我们关注一下开方本身的特殊性

    我们知道,如果每次向下取整,一个数经过多次操作最终会变成1(或0)

    事实上,大概经过 log(logx)次就会变成1

    这是什么概念呢?经过博主测试,1e9只要经过五次开方取整就会变成1

    那么接下来就能够利用1每次不必再操作优化复杂度

    可以维护一个类似链表的结构,指向下一个>1的数,用并查集维护

    并查集+树状数组这两种常数极小的结构组合起来简直快的飞起:

    蒟蒻第一次上榜有点激动Orz

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cmath>
    using namespace std;
    
    const int L=1<<20|1;
    char buffer[L],*S,*T;
    #define getchar() ((S==T&&(T=(S=buffer)+fread(buffer,1,L,stdin),S==T))?EOF:*S++)
    
    
    typedef long long ll;
    const int N=100005;
    ll c[N];
    int n,m,data[N],fa[N];
    inline int read()
    {
        int f=1,x=0;char ch=getchar();
        while(ch<'0'||ch>'9')
        {if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9')
        {x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    int lb(int x){return x&-x;}
    int findf(int x)
    {
        if(x==fa[x])return x;
        fa[x]=findf(fa[x]);
        return fa[x];
    }
    void update(int p,int v)
    {
        while(p<=n)c[p]+=v,p+=lb(p);
    }
    ll sum(int p)
    {
        ll res=0;
        while(p)res+=c[p],p-=lb(p);
        return res;
    }
    int main()
    {
        n=read();
        for(int i=1;i<=n;i++)data[i]=read(),update(i,data[i]);
        m=read();
        for(int i=1;i<=n;i++)fa[i]=data[i]<=1?i+1:i;
        fa[n+1]=n+1;
        while(m--)
        {
            int op=read(),l=read(),r=read();
            if(op==1)printf("%lld
    ",sum(r)-sum(l-1));
            else if(op==2)
                for(int i=l;i<=r;i=findf(i+1))
                {
                    int sqt=(int)sqrt(data[i]);
                    update(i,sqt-data[i]),data[i]=sqt;    
                    if(data[i]<=1)fa[i]=findf(i+1);
                }
        }
        return 0;
    }
    View Code
  • 相关阅读:
    fdisk 分区
    fdisk 添加逻辑分区
    centos7 bond0 双网卡配置
    查看centos7启动项
    本地yum源安装docker
    cobbler Ubuntu16.04 安装
    docker-ce-17.03.2 离线安装RPM包
    day14 生成器的进阶
    day13迭代器与生成器
    day12闭包,装饰器
  • 原文地址:https://www.cnblogs.com/Rorschach-XR/p/11008046.html
Copyright © 2011-2022 走看看