• 上帝造题的七分钟2 / 花神游历各国


    洛咕

    双倍经验 洛咕

    题意:给定长度为(N(N<=100000))的序列,操作一:将区间([l,r])中的每个数都开方(向下取整),操作二:查询区间和.

    分析:题解真妙啊...因为题目保证了序列中最大的数不会超过(10^{12}),而(10^{12})开方并且向下取整的话只要6次就能开到只剩1((10^{12}->10^6->10^3->31->5->2->1)),而对于开到1的数显然对于操作一可以忽略,所以我们直接对于不为1的数暴力开方即可.

    具体来说,我们建一棵线段树,每个节点记录maxn和sum值,即区间最大值和区间和,对于操作一,如果该节点的maxn>1就暴力开方修改,否则可以忽略.对于操作二就很普通了.

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #include<queue>
    #include<map>
    #include<set>
    #define ll long long
    using namespace std;
    inline ll read(){
        ll x=0,o=1;char ch=getchar();
        while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
        if(ch=='-')o=-1,ch=getchar();
        while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
        return x*o;
    }
    const int N=100005;
    ll a[N];
    struct xd_tree{
    	int l,r;ll maxn,sum;
    }t[N*4];
    inline void build(int p,int l,int r){
    	t[p].l=l;t[p].r=r;
    	if(l==r){t[p].maxn=t[p].sum=a[l];return;}
    	int mid=(l+r)>>1;
    	build(p<<1,l,mid);build((p<<1)|1,mid+1,r);
    	t[p].sum=t[p<<1].sum+t[(p<<1)|1].sum;
    	t[p].maxn=max(t[p<<1].maxn,t[(p<<1)|1].maxn);
    }
    inline void change(int p,int l,int r){
        if(t[p].l==t[p].r){
            t[p].maxn=t[p].sum=sqrt(t[p].sum);
            return;
        }   
        int mid=(t[p].l+t[p].r)>>1;
        if(l<=mid&&t[p<<1].maxn>1)change(p<<1,l,r);
        if(r>mid&&t[(p<<1)|1].maxn>1)change((p<<1)|1,l,r);
        t[p].sum=t[p<<1].sum+t[(p<<1)|1].sum;
    	t[p].maxn=max(t[p<<1].maxn,t[(p<<1)|1].maxn);
    }
    inline ll ask(int p,int l,int r){
    	if(l<=t[p].l&&r>=t[p].r)return t[p].sum;
    	int mid=(t[p].l+t[p].r)>>1;
    	ll val=0;
    	if(l<=mid)val+=ask(p<<1,l,r);
    	if(r>mid)val+=ask((p<<1)|1,l,r);
    	return val;
    }
    int main(){
    	int n=read();for(int i=1;i<=n;++i)a[i]=read();	
    	build(1,1,n);int m=read();
    	while(m--){
    		int k=read(),l=read(),r=read();
    		if(l>r)swap(l,r);
    		if(k==0)change(1,l,r);
    		if(k==1)printf("%lld
    ",ask(1,l,r));
    	}
        return 0;
    }
    
    
  • 相关阅读:
    如何用正确的方法写出高质量软件的75条体会(转)
    使用javascript动态添加onclick事件,
    签名和重载
    C#文件后缀名详解
    配置SQL Server 2005 Express的身份验证方式,以及如何启用sa登录名。
    CSS选择符及优先级计算
    关于软件版本的解释
    数据结构形象解释
    CSS属性选择符
    [转载]Repeater三层嵌套
  • 原文地址:https://www.cnblogs.com/PPXppx/p/11346030.html
Copyright © 2020-2023  润新知