Yih的线段树(线段树计数)

题意

在线段树中,执行完build(1,1,n)后,节点\(x\)被创建,且在所有被创建节点中,节点\(x\)的节点编号最大,则称\(x\)的编号是一个Yuzu数。

给定\(Q\)个数字\(x_i\),问\(x_i\)是否是Yuzu数。

题目链接:https://www.acwing.com/problem/content/4585/

数据范围

\(1 \leq Q \leq 10^5\)
\(1 \leq x_i \leq 10^9\)

思路

这道题赛场上做出来了,但是因为考过好几次了,所以在这里记录一下结论。

这种题就是打表找规律。规律如下:

首先我们将\(n = 2^k\)的情况,记为基准点。在基准点上,最大编号是\(2n-1\)。然后出现的最大编号是\(2n+1,3n+1,3n+\frac{n}{2}+1, 3n+\frac{n}{2}+\frac{n}{4}+1, \dots, 3n+\frac{n}{2}+\cdots + 4 + 1\)

代码

#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <map>

using namespace std;

typedef long long ll;

map<ll, int> mp;

int main()
{
    mp[1] = 1;
    for(ll i = 2; i <= 1000000000; i *= 2) {
        ll t = i * 4 - 1;
        mp[2 * i - 1] = 1;
        mp[2 * i + 1] = 1;
        ll tmp = 3 * i + 1, p = i;
        while(tmp < t) {
            mp[tmp] = 1;
            p /= 2;
            tmp += p;
        }
    }
    int T;
    scanf("%d", &T);
    while(T --) {
        int x;
        scanf("%d", &x);
        if(mp[x]) puts("Y");
        else puts("N");
    }
    return 0;
}
posted @ 2022-08-16 10:33  pbc的成长之路  阅读(36)  评论(0编辑  收藏  举报