codeVS第二次月赛 C

题目描述 Description

切记不要加任何文件读写, 本次比赛暂不支持ifndef ONLINE_JUDGE。请互相转告。评测机是linux

Jijijie是恐怖的科学怪人,他有特殊的邪恶科技 Song'ci Crash。

Dash在他的家庭农场里拥有 n块连续的拥有者黑色和金色混杂的 Da'shgua田地。Song'ci Crash攻击会使连续的一段  Da'shgua田地遭受打击, 会使编号在 [L,R]范围内的田地产量从 x(x!=0)变为floor(ln(x))。tty,Long'Aotian职阶的骑士,将驾驶他的 knightmare,tgopknight,来迎战 Jijijie。tty每夺回一块 Da'shgua田地,这块田地就会在 Owaski天神的庇护下获得生机,使田地产量突变。

国王 Papafish急不可耐地想知道战况如何,他会询问连续的一段Da'shgua田地的产量之和。

机智的你,能回答他的询问吗?

    题解:考场上乍一眼看是一道线段树裸题,然而注意到区间log并不是一样的,所以就把区间改写成了暴力一个一个改,然后没有考虑log(0)不合法的情况,所以爆0了。

按照题目给定的范围,最多log4次就变成0了,所以我们只要在线段树上把区间内sum不为0的数进行修改即可,最多4n,可过。(TM还真是一道线段树裸题)。

%%%__debug大神。

#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
const int MAXN=100001,MAXM=400001,MAXNODE=3*MAXN;
int n,m,w[MAXN];
struct SegMentTree{
	long long sum[MAXNODE];
	SegMentTree(){memset(sum,0,sizeof(sum));}
	void maintain(int now)
	{
		int lc=now<<1,rc=now<<1|1;
		sum[now]=sum[lc]+sum[rc];
	}
	void set(int now,int l,int r,int o,int v)
    {
        if(l==r&&l==o)
        {
            sum[now]=0;
            sum[now]+=v;
            return;
        }
        int mid=(l+r)>>1,lc=now<<1,rc=now<<1|1;
        if(o<=mid)
           set(lc,l,mid,o,v);
        else 
            set(rc,mid+1,r,o,v);
        maintain(now);
    }
    void query(int now,int l,int r,int ql,int qr,long long& ans)
    {
        if(l>=ql&&r<=qr)
        {
            ans+=sum[now];
            return;
        }
        int mid=(l+r)>>1,lc=now<<1,rc=now<<1|1;
        if(ql<=mid)
            query(lc,l,mid,ql,qr,ans);
        if(qr>mid)
            query(rc,mid+1,r,ql,qr,ans);
    }
    void change(int now,int l,int r,int ql,int qr)
    {
    	if(!sum[now])return;
    	if(l==r)
    	{
    		sum[now]=log(sum[now]);
    		return;
    	}
    	int mid=(l+r)>>1,lc=now<<1,rc=now<<1|1;
    	if(ql<=mid)
    		change(lc,l,mid,ql,qr);
    	if(qr>mid)
    		change(rc,mid+1,r,ql,qr);
    	maintain(now);
    }
}Tree;
void Read(int &x)
{
	x=0;int flag=0;char c;
	while(c=getchar())
	{
		if(c>='0'&&c<='9'){flag=1;x*=10;x+=c-'0';}
		else if(flag)break;
	}
}
int main()
{
	freopen("C.in","r",stdin);
	freopen("C.out","w",stdout);
	Read(n);Read(m);
	for(int i=1;i<=n;i++)
	{
		int a;
		Read(a);
		Tree.set(1,1,n,i,a);
	}
	int op,a,b;
	for(int i=1;i<=m;i++)
	{
		long long ans=0;
		Read(op);Read(a);Read(b);
		if(op==1)
			Tree.set(1,1,n,a,b);
		else if(op==2)
			Tree.change(1,1,n,a,b);
		else if(op==3)
		{
			Tree.query(1,1,n,a,b,ans);
			printf("%I64d\n",ans);
		}
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值