BZOJ-3211花神游历各国 并查集+树状数组
一开始想写线段树区间开方,简单暴力下,但觉得变成复杂度稍高,懒惰了,编了个复杂度简单的 
3211: 花神游历各国 
Time Limit: 5 Sec  Memory Limit: 128 MB 
Submit: 1706  Solved: 651 
[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 
11 
11 
HINT 
对于100%的数据, n ≤ 100000,m≤200000 ,data[i]非负且小于10^9
这道题一打眼看就是区间操作,就想到线段树和树状数组,一开始想暴力开根到1为止,写个线段树区间开方
但感觉编程复杂度相对较高,外加时间复杂度不低,于是写了个树状数组+并查集
树状数组的用处不用多说,并查集的用处比较精妙:
用并查集维护一下,维护每个数右边第一个不为1的数字,暴力开根,
如果开根成1后,把他的父亲连到右边数的父亲上,这样在连续修改上,就可以跳过大量连续的1了
666666
代码如下:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
#define maxn 100001
long long love[maxn]={0};
int past[maxn]={0};
int father[maxn]={0};
int n;
int lowbit(int x)
{
    return x&(-x);
}
void change(int loc,int data)
{
    while (loc<=n)
        {
            love[loc]+=data;
            loc+=lowbit(loc);
        }
}
long long sum(int loc)
{
    long long tot=0;
    while (loc>0)
        {
            tot+=love[loc];
            loc-=lowbit(loc);
        }
    return tot;
}
int find(int x)
{
    if (x==father[x])
        return x;
    else
        {
            father[x]=find(father[x]);
            return father[x];
        }
}
int main()
{
    scanf("%d",&n);
    for (int i=1; i<=n; i++)
        {
            int x;
            scanf("%d",&x);
            change(i,x);
            past[i]=x;
            if (past[i]<=1)
                father[i]=i+1;
            else
                father[i]=i;//一开始对father的初始化
        }
    int m;
    father[n+1]=n+1;
    scanf("%d",&m);
    for (int i=1; i<=m; i++)
        {
            int command,l,r;
            scanf("%d%d%d",&command,&l,&r);
            if (command==1)
                {
                    long long ans=sum(r)-sum(l-1);
                    printf("%lld\n",ans);
                }
            else
                {
                    for (l=find(l); l<=r; l=find(l+1))
                        {
                            int delta=floor(sqrt(past[l]));
                            change(l,delta-past[l]);//变成开根的方法,就是先减掉自己本身再加上开根,所以可以直接减去自身和开根的差
                            past[l]=delta;
                            if (past[l]==1)
                                father[l]=find(l+1);//如果开根到1了,就把father连到右边数的father上
                        }
                }
        }
    return 0;
} 
话说这个题后来修改时T了一遍,W了一遍,懵懂中搜索了一下,竟是我DCrusher蛋哥的blog,可惜蛋神做法太高端,于是还是自己修改去了,╮(╯▽╰)╭
BZOJ-3211花神游历各国 并查集+树状数组的更多相关文章
- BZOJ3211 花神游历各国 并查集 树状数组
		
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ3211 题意概括 有n个数形成一个序列. m次操作. 有两种,分别是: 1. 区间开根(取整) 2. ...
 - 【BZOJ3211】花神游历各国 并查集+树状数组
		
[BZOJ3211]花神游历各国 Description Input Output 每次x=1时,每行一个整数,表示这次旅行的开心度 Sample Input 41 100 5 551 1 22 1 ...
 - BZOJ 3038 上帝造题的七分钟2 (并查集+树状数组)
		
题解:同 BZOJ 3211 花神游历各国,需要注意的是需要开long long,还有左右节点需要注意一下. #include <cstdio> #include <cmath> ...
 - hdu 6200 mustedge mustedge(并查集+树状数组 或者 LCT 缩点)
		
hdu 6200 mustedge mustedge(并查集+树状数组 或者 LCT 缩点) 题意: 给一张无向连通图,有两种操作 1 u v 加一条边(u,v) 2 u v 计算u到v路径上桥的个数 ...
 - 【bzoj4869】[Shoi2017]相逢是问候  扩展欧拉定理+并查集+树状数组
		
题目描述 Informatik verbindet dich und mich. 信息将你我连结. B君希望以维护一个长度为n的数组,这个数组的下标为从1到n的正整数.一共有m个操作,可以分为两种:0 ...
 - BZOJ 3211: 花神游历各国( 线段树 )
		
线段树...区间开方...明显是要处理到叶节点的 之前在CF做过道区间取模...差不多, 只有开方, 那么每个数开方次数也是有限的(0,1时就会停止), 最大的数10^9开方10+次也就不会动了.那么 ...
 - BZOJ 3211: 花神游历各国【线段树区间开方问题】
		
3211: 花神游历各国 Time Limit: 5 Sec Memory Limit: 128 MBSubmit: 3514 Solved: 1306[Submit][Status][Discu ...
 - BZOJ 3211 花神游历各国 (树状数组+并查集)
		
题解:首先,单点修改求区间和可以用树状数组实现,因为开平方很耗时间,所以在这个方面可以优化,我们知道,开平方开几次之后数字就会等于1 ,所以,用数组记录下一个应该开的数,每次直接跳到下一个不是1的数字 ...
 - BZOJ 3038: 上帝造题的七分钟2 / BZOJ 3211: 花神游历各国 (线段树区间开平方)
		
题意 给出一些数,有两种操作.(1)将区间内每一个数开方(2)查询每一段区间的和 分析 普通的线段树保留修改+开方优化.可以知道当一个数为0或1时,无论开方几次,答案仍然相同.所以设置flag=1变表 ...
 
随机推荐
- Android配置----Eclipse+BlueStacks调试Android应用
			
[声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/3 ...
 - linux下查找某个目录下包含某个字符串的文件
			
有时候要找一些字符串,但是又不知道在哪个文件,只记得一些字符串 那么如何在linux下寻找包含某段文字的文件呢? 强大的find命令可以帮你完成不可能的任务. 比如我只记得我的程序里包含唯一的字符串“ ...
 - java8-1 final
			
1.final可以修饰类,方法,变量 特点: final可以修饰类,该类不能被继承. final可以修饰方法,该方法不能被重写.(覆盖,复写) final可以修饰变量,该变量不能被重新赋值.因为这个变 ...
 - Android SQLite (四 ) 全面详解(二)
			
SQLite创建数据库 创建数据库语法: sqlite3 DatabaseName.db 如下展示一个实例: SQLite附加数据库 假设这样一种情况,当在同一时间有多个数据库可用,您想使用其中的任何 ...
 - 用于json的  .ashx 小细节
			
public void ProcessRequest(HttpContext context) { switch (action) { case "attribute_field_valid ...
 - jQuery on(),live(),trigger()
			
jQuery on()方法是官方推荐的绑定事件的一个方法. $(selector).on(event,childSelector,data,function,map); 由此扩展开来的几个以前常见的方 ...
 - result默认返回action中的所有数据,要想返回指定的数据怎么做呢
			
result默认返回action中的所有数据,要想返回指定的数据怎么做呢?
 - 图解HTTP看书体会(1)
			
MAC地址和IP地址的区别与联系 一.IP地址 对于IP地址,相信大家都很熟悉,即指使用TCP/IP协议指定给主机的32位地址.IP地址由用点分隔开的4个8八位组构成,如192.168.0.1就是一个 ...
 - log4j发送邮件乱码
			
Log4J发日志邮件给多个接收者及标题.正文乱码问题 以前开发的系统没有单独的日志管理,所有的日志统一输出到tomcat后台一个文件里,不几天就是好几G,现在要整体增加一个Log4J管理日志的功能,其 ...
 - nginx安装pcre
			
一.有的服务器上没有安装pcre那么安装nginx的时候会报错 所以在安装之前我们可以: yum install pcre-devel 如果很不巧,服务器也没有配yum,也不能连互联网.那么我们只能自 ...