BZOJ 3211 弗洛拉前往国家 树阵+并检查集合

标题效果:给定一个序列,它提供了以下操作:

1.将[l.r]每个号码间隔a[i]变sqrt(a[i])

2.查询[l,r]间隔和

剧烈的变化不支持由间隔,因此,我们选择单 - 点更换间隔查询的树阵,但是,这是O(n^2)的,怎么办?

我们发现一个数x最多开loglogx次根号就会变为1 也就是一个int范围内的数仅仅要开6次根号就会变为1 于是改动的总时间复杂度为O(nloglogn)

可是单次改动怎么办?我们维护一个并查集。一旦一个数为1或0,我们就把这个位置的father设为它右面的那个位置就可以 这样能够均摊O(n)时间找到一个数后面第一个>1的数

此外此题增加读入优化能够快一倍 令人非常费解0.0

#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define M 100100
using namespace std;
typedef long long ll;
int n,m,a[M],fa[M];
ll c[M];
inline int getc() {
    static const int L = 1 << 15;
    static char buf[L], *S = buf, *T = buf;
    if (S == T) {
        T = (S = buf) + fread(buf, 1, L, stdin);
        if (S == T)
            return EOF;
    }
    return *S++;
}
inline int getint() {
    int c;
    while(!isdigit(c = getc()) && c != '-');
    bool sign = c == '-';
    int tmp = sign ?

0 : c - '0';
    while(isdigit(c = getc()))
        tmp = (tmp << 1) + (tmp << 3) + c - '0';
    return sign ? -tmp : tmp;
}
int Find(int x)
{
	if(!fa[x]||fa[x]==x)
		return fa[x]=x;
	return fa[x]=Find(fa[x]);
}
void Update(int x,int y)
{
	for(;x<=n;x+=x&-x)
		c[x]+=y;
}
ll Get_Ans(int x)
{
	ll re=0;
	for(;x;x-=x&-x)
		re+=c[x];
	return re;
}
void Modify(int x,int y)
{
	int i=x;
	for( i=x ; i<=y ; i=Find(i+1) )
	{
		int temp=(int)sqrt(a[i]);
		Update(i,temp-a[i]);
		a[i]=temp;
		if(a[i]<=1)
			fa[i]=Find(i+1);
	}
}
int main()
{
	int i,p,x,y;
	cin>>n;
	for(i=1;i<=n;i++)
	{
		a[i]=getint();
		if(a[i]==1||!a[i])
			fa[i]=i+1;
		Update(i,a[i]);
	}
	m=getint();
	for(i=1;i<=m;i++)
	{
		p=getint();
		x=getint();
		y=getint();
		if(p==1)
			printf("%lld\n", Get_Ans(y)-Get_Ans(x-1) );
		else
			Modify(x,y);
	}
}
时间: 2024-10-17 12:01:39

BZOJ 3211 弗洛拉前往国家 树阵+并检查集合的相关文章

BZOJ 3211 花神游历各国 树状数组+并查集

题目大意:花神对每一个国家有一个喜爱程度,有的时候他会对连续的一段国家进行访问,求他的喜爱程度的和:有的时候他会对连续的一段国家产生厌恶,喜爱程度变成sqrt(x)下取整. 思路:乍一看好像是RMQ问题,用线段树就可以水过,但是开根号的标记怎么下传?这是一个严重的问题,所以我们要换一个思路. 注意到开根号有一个有趣的性质:sqrt(1) = 1,sqrt(0) = 0,而且所有的数字经过有限次的开根号运算都会变成1.这个性质就很好了.我们对每一个点暴力开根号,然后当这个店的点权变成1的时候就打一

BZOJ 3211 花神游历各国 树状数组(线段树)+优化

题意:给你一段区间,然后每个点的初始值都告诉你,现有两种操作,一种是给你一个小区间的左右端点,之后把这个区间内的所有值都开根号,另一种就是区间求值. 方法:树状数组维护求和,巧妙开根号.(线段树) 解析:这道是某次考试考的题- -.当时也没想到快的开根号方法,暴力开根号好像70分吧. 首先要明确一个事情:被开根号的数最大是109,而109开几次会开到1呢?用计算器算一下发现5次就将这个最大的数开到1了,而1开根号怎么开都是1,所以如果再对其进行开根号操作,仅仅是无用的浪费时间了.所以怎么维护这种

BZOJ 3211 花神游历各国 线段树题解

BZOJ 3211 花神游历各国 线段树题解 3211: 花神游历各国 Time Limit: 5 Sec  Memory Limit: 128 MBSubmit: 2551  Solved: 946[Submit][Status][Discuss] Description Input Output 每次x=1时,每行一个整数,表示这次旅行的开心度 Sample Input 4 1 100 5 5 5 1 1 2 2 1 2 1 1 2 2 2 3 1 1 4 Sample Output 101

BZOJ 3211 花神游历各国 (树状数组+并查集)

题解:首先,单点修改求区间和可以用树状数组实现,因为开平方很耗时间,所以在这个方面可以优化,我们知道,开平方开几次之后数字就会等于1 ,所以,用数组记录下一个应该开的数,每次直接跳到下一个不是1的数字进行开平方,至于这个数组,可以用并查集维护. #include <cstdio> #include <cmath> #include <iostream> using namespace std; typedef long long LL; LL c[100005]; in

BZOJ 1502:月下柠檬树

BZOJ 1502:月下柠檬树 题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1502 题目大意:给出一棵有圆台构成的树以及一个平行光源,问树的阴影面积. 计算几何 Simpson积分 第一次写计算几何题,一直wa...明天补

bzoj 2120: 数颜色 线段树套平衡树

/************************************************************** Problem: 2120 User: wangyucheng Language: C++ Result: Time_Limit_Exceed ****************************************************************/ #include<iostream> #include<cstdio> #incl

URAL 1707. Hypnotoad&amp;#39;s Secret(树阵)

URAL 1707. Hypnotoad's Secret space=1&num=1707" target="_blank" style="">题目链接 题意:这题设置的恶心不能多说.构造点和矩形.大概就是问每一个矩形里面是否包括点 思路:树状数组.把点排序,按y轴,在按x轴.在按询问,这样每次遇到一个点就在对应的扫描线上加.遇到查询就询问出左边到这个点位置的,就能预处理出每一个点左下角包括的点的个数,然后每一个矩形再利用容斥原理去搞一下就

HDOJ 5147 Sequence II 树阵

树阵: 每个号码的前面维修比其数数少,和大量的这后一种数比他的数字 再枚举每一个位置组合一下 Sequence II Time Limit: 5000/2500 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 121    Accepted Submission(s): 58 Problem Description Long long ago, there is a sequen

BZOJ 1089 严格n元树 (递推+高精度)

题解:用a[i]表<=i时有几种树满足度数要求,那么这样就可以递归了,a[i]=a[i-1]^n+1.n个节点每个有a[i-1]种情况,那么将其相乘,最后加上1,因为深度为0也算一种.那么答案就是a[n]-a[n-1].然后就是高精度的问题了,发现很久没有现码高精度没手感了,连高进度加法进位都出了些问题,需要特别注意. #include <cstdio> #include <cstring> #include <algorithm> using namespace