zoukankan      html  css  js  c++  java
  • [BZOJ3211]:花神游历各国(小清新线段树)

    题目传送门


    题目描述

    花神喜欢步行游历各国,顺便虐爆各地竞赛。花神有一条游览路线,它是线型的,也就是说,所有游历国家呈一条线的形状排列,花神对每个国家都有一个喜欢程度(当然花神并不一定喜欢所有国家)。

    每一次旅行中,花神会选择一条旅游路线,它在那一串国家中是连续的一段,这次旅行带来的开心值是这些国家的喜欢度的总和,当然花神对这些国家的喜欢程序并不是恒定的,有时会突然对某些国家产生反感,使他对这些国家的喜欢度$delta$变为$sqrt{delta}$(可能是花神虐爆了那些国家的 OI,从而感到乏味)。

    现在给出花神每次的旅行路线,以及开心度的变化,请求出花神每次旅行的开心值。


    输入格式

    第一行是一个整数N,表示有N个国家;
    第二行有N个空格隔开的整数,表示每个国家的初始喜欢度;
    第三行是一个整数M,表示有M条信息要处理;
    第四行到最后,每行三个整数想x,l,r,当x=1时询问游历国家x到r的开心值总和,也就是$sum limits_{i=l}^{r} delta_{i}$x=2时国家l到r中每个国家的喜欢度$delta_{i}$变为$sqrt{delta_{i}}$


    输出格式

    每次x=1时,每行一个整数。表示这次旅行的开心度。


    样例

    样例输入:

    4
    1 100 5 5
    5
    1 1 2
    2 1 2
    1 1 2
    2 2 3
    1 1 4

    样例输出:

    101
    11
    11


    数据范围与提示

    对于全部数据,1≤n≤105,1≤m≤2×105,1≤l≤r≤n,0≤$delta_{i}$≤109

    注:建议使用sqrt函数,且向下取整。


    一句话题意:线段树区间开跟,区间求和。


    题解

    区间信息无法快速更新,无法使用延迟标记。(可怕)

    但是注意,109最多开5次跟就不变了

    那么,每次修改暴力递归下去,直到当前区间已全是0或1就return

    是不是很帅?


    代码时刻

    #include<bits/stdc++.h>
    #define L(x) x<<1
    #define R(x) x<<1|1
    using namespace std;
    int n,m;
    long long v[100001];
    long long trsum[400001],trmax[400001];
    void pushup(int x)
    {
    	trsum[x]=trsum[L(x)]+trsum[R(x)];
    	trmax[x]=max(trmax[L(x)],trmax[R(x)]);
    }
    void build(int x,int l,int r)
    {
    	if(l==r)
    	{
    		trsum[x]=trmax[x]=v[l];
    		return;
    	}
    	int mid=(l+r)>>1;
    	build(L(x),l,mid);
    	build(R(x),mid+1,r);
    	pushup(x);
    }
    void change(int x,int l,int r,int L,int R)
    {
    	if(l==r)
    	{
    		trsum[x]=sqrt(trsum[x]);
    		trmax[x]=sqrt(trmax[x]);
    		return;
    	}
    	if(trmax[x]<=1)return;//注意这里为≤,其他跟普通线段树别无两样 
    	int mid=(l+r)>>1;
    	if(L<=mid)change(L(x),l,mid,L,R);
    	if(R>mid)change(R(x),mid+1,r,L,R);
    	pushup(x);
    }
    long long ask(int x,int l,int r,int L,int R)
    {
    	if(L<=l&&r<=R)return trsum[x];
    	int mid=(l+r)>>1;
    	long long rec=0;
    	if(L<=mid)rec+=ask(L(x),l,mid,L,R);
    	if(R>mid)rec+=ask(R(x),mid+1,r,L,R);
    	return rec;
    }
    int main()
    {
    	scanf("%d",&n);
    	for(int i=1;i<=n;i++)
    		scanf("%lld",&v[i]);
    	build(1,1,n);
    	scanf("%d",&m);
    	while(m--)
    	{
    		int op,l,r;
    		scanf("%d%d%d",&op,&l,&r);
    		if(op==1)printf("%lld
    ",ask(1,1,n,l,r));
    		else change(1,1,n,l,r);
    	}
    	return 0;
    }
    

    rp++

  • 相关阅读:
    手写redux
    require.context
    webpack cdn加速
    spy-debugger安装、调试步骤
    MAC设置应用在127.0.0.1:80
    javascript数据结构——栈
    Immutable.js了解一下?
    自己搭建服务器.并返回结果
    vue-cli2与vue-cli3在一台电脑共存
    JavaScript点击事件-一个按钮触发另一个按钮
  • 原文地址:https://www.cnblogs.com/wzc521/p/11015134.html
Copyright © 2011-2022 走看看