NOIP模拟赛 斐波那契树 + 二分 + 并查集

FIbonacci

这里写图片描述

m <= 3e5. 询问的数字是10^12级别的.

题解

首先很明显肯定要log的算法. 并且由于斐波那契的性质, 树高一定是log级别的. 那么对于两个点我们只要暴力跳fa即可过.
问题就在于怎么快速求father.
比如编号i的他的fa是谁. 我们想这个树每次生成f[j]个(f是斐波那契数列). 那么i一定是某一批斐波那契数列. 那么我们知道这一批之前一共生成了多少个的话, 那么用i-这个数量之后就是i在这一批第几个生成, 那么也就是i的父亲.
然而之前一共生成的实际上也是一个斐波那契数, 并且是刚好比i小的斐波那契数.
因为你看这棵树初始三批都是1. 那么i之前的数量就是f[1] + f[1] + f[2] + f[3] + f[4] + …f[i - 1] (f[1] = f[2] = 1). 我们把f[1]跟f[1]配生成f[2], f[2]跟f[3]生成f[4]…模拟一下就发现多了一个f[1]之后就也是一个斐波那契数. 也就是说斐波那契数的前缀和 + 1也是一个斐波那契数.
那么每次找fa二分即可. fa就是自己 - 刚好比自己小的斐波那契数. 二分斐波那契数列即可. 注意斐波那契数只需60项就 > 10 ^ 12.

#include<stdio.h>
#include<map>
using namespace std;
typedef long long dnt;
int T;
dnt f[65];
inline int find(dnt pos){
    int lf = 1, rg = 60, ans = 1;
    while(lf <= rg){
        int mid = (lf + rg) >> 1;
        if(f[mid] < pos) ans = mid, lf = mid + 1;
        else rg = mid - 1;
    }
    return ans;
}
inline void init(){
    f[1] = 1;   
    for(int i = 2; i <= 60; ++i)
        f[i] = f[i - 1] + f[i - 2];
}
int main(){
    freopen("fibonacci.in", "r", stdin);
    freopen("fibonacci.out", "w", stdout);
    init();
    scanf("%d", &T);
    while(T--){
        dnt a, b;
        scanf("%I64d%I64d", &a, &b);
        while(true){
            if(a == b) {printf("%I64d\n", a); break;}
            if(a < b) swap(a, b);
            a -= f[find(a)];
        }
    }
    return 0;
}

Color

给定一个正整数序列, 询问l到r值c的有多少个. 支持将i+1和i+2的值交换的修改操作. 询问及操作数量 <= 3e5, n <= 3e5, ai <= 3e5.

题解

班上居然很多人写了主席树…一看这道题就是普通的二分.
用vector存每个值在整个序列中出现的位置(单调上升). 那么询问l到r的c有多少个就在c的vector里二分即可.
交换操作也是直接修改.

Division

这里写图片描述

K <= 2, ai <= 130000, n <= 130000.

题解

贪心的想, 肯定是从后往前选, 每一段选得越多越好. 这样就既能满足字典序最小并且组数最少.
那么现在就考虑每一段如何check合不合法.
如果K == 1的话, 直接枚举平方数即可. 就520个.
K = 2的话. 判断一段发现就是分成两个集合. 会发现跟bzoj团伙或者noip关押罪犯的镜像并查集一样.
注意某ai*2也是平方数的话就要特判.

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值