zoukankan      html  css  js  c++  java
  • 题解 SP2713 【GSS4

    用计算器算一算,就可以发现(10^{18})的数,被开方(6)次后就变为了(1)

    所以我们可以直接暴力的进行区间修改,若这个数已经到达(1),则以后就不再修改(因为(1)开方后还是(1)),用并查集和树状数组进行维护。

    这个方法用了P2391 白雪皑皑的思想处理,用并查集标记该点已经不再用替换。

    和我这题CF920F【SUM和REPLACE】的方法相同。

    (code):

    #include<bits/stdc++.h>
    #define maxn 500010
    #define lowbit(x) (x&(-x))
    typedef long long ll;
    using namespace std;
    ll n,m;
    ll fa[maxn],k,l,r;
    ll a[maxn],tree[maxn];
    int cnt;
    int find(int x)
    {
    	return fa[x]==x?x:fa[x]=find(fa[x]);
    }
    void add(int x,ll d)
    {
    	while(x<=n)
    	{
    		tree[x]+=d;
    		x+=lowbit(x);
    	}
    }
    ll query(int x)
    {
    	ll sum=0;
    	while(x)
    	{
    		sum+=tree[x];
    		x-=lowbit(x);
    	}
    	return sum;
    }
    int main()
    {
    	while(scanf("%lld",&n)!=EOF)
    	{
    		cnt++;
    		printf("Case #%d:
    ",cnt);
    		for(int i=1;i<=n*4;++i)
    		tree[i]=0;
    		for(int i=1;i<=n;++i)
    		{
    			scanf("%lld",&a[i]);
    			add(i,a[i]);
    			fa[i]=i;
    		}
    		fa[n+1]=n+1;
    		scanf("%lld",&m);
    		while(m--)
    		{
    			scanf("%lld%lld%lld",&k,&l,&r);
    			if(l>r)
    			swap(l,r);
    			if(k==0)
    			{
    				for(int i=l;i<=r;)
    				{
    					add(i,(ll)sqrt(a[i])-a[i]);//手动暴力开方
    					a[i]=(ll)sqrt(a[i]);
    					if(a[i]<=1)
    					fa[i]=i+1;//若这个数已经为1,则将其指向它下一个数	
    					if(i==find(i))
    					i++;
    					else
    					i=fa[i];//进行跳转,忽略不再需要开方的数
    				}
    			}
    			else
    			printf("%lld
    ",query(r)-query(l-1));
    		}
    		printf("
    ");
    	}
    	return 0;
    }
    
  • 相关阅读:
    PTA——List Leaves
    pta——电话聊天狂人(c二叉树实现)
    Anti-SG游戏 与 SJ定理笔记(反Nim博弈)
    Unicode代码点与代码单元
    奇偶校验位
    IPv6与IPv4的位数
    0- win10配置java环境变量问题
    小计划
    路径问题
    getResource(path)的注意事项
  • 原文地址:https://www.cnblogs.com/lhm-/p/12229808.html
Copyright © 2011-2022 走看看