BZOJ5300 [Cqoi2018]九连环 【dp + 高精】

题目链接

BZOJ5300

题解

这题真的是很丧病,,卡高精卡到哭

我们设\(f[i]\)表示卸掉前\(i\)个环需要的步数

那么

\[f[i] = 2*f[i - 2] + f[i - 1] + 1\]

直接高精递推不仅\(MLE\)而且\(TLE\)

然后就要用到数学求通项公式,或者打表找规律

\[f[n] = \lfloor \frac{2^(n + 1)}{3} \rfloor\]

高精乘低精就可以过了

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<map>
#define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt)
#define REP(i,n) for (int i = 1; i <= (n); i++)
#define mp(a,b) make_pair<int,int>(a,b)
#define cls(s) memset(s,0,sizeof(s))
#define cp pair<int,int>
#define LL long long int
using namespace std;
const int maxn = 100005,B = 100000000,maxm = 100005,INF = 1000000000;
inline int read(){
    int out = 0,flag = 1; char c = getchar();
    while (c < 48 || c > 57){if (c == ‘-‘) flag = -1; c = getchar();}
    while (c >= 48 && c <= 57){out = (out << 3) + (out << 1) + c - 48; c = getchar();}
    return out * flag;
}
struct NUM{
    LL s[100000],len;
    NUM(){cls(s); len = 0;}
    void out(){
        if (!len){putchar(‘0‘); return;}
        printf("%lld",s[len - 1]);
        for (int i = len - 2; i >= 0; i--)
            printf("%08lld",s[i]);
    }
}F;
inline void operator *=(NUM& a,const int& b){
    LL tmp,carry = 0;
    for (int i = 0; i < a.len; i++){
        tmp = 1ll * a.s[i] * b + carry;
        a.s[i] = tmp % B;
        carry = tmp / B;
    }
    while (carry) a.s[a.len++] = carry % B,carry /= B;
}
inline NUM operator /(const NUM& a,const int& b){
    NUM c;
    c.len = a.len;
    LL tmp,carry = 0;
    for (int i = a.len - 1; i >= 0; i--){
        tmp = a.s[i] + 1ll * carry * B;
        if (tmp < b) c.s[i] = 0,carry = tmp;
        else c.s[i] = tmp / b,carry = tmp % b;
    }
    //if (carry) c = c + 1;
    while (c.len && !c.s[c.len - 1]) c.len--;
    return c;
}
int main(){
    int T = read();
    while (T--){
        int n = read() + 1,bin = 1 << 30;
        F.len = 1; F.s[0] = 1;
        int tmp = n / 30,t = n % 30;
        while (tmp--) F *= bin;
        while (t--) F *= 2;
        F = F / 3;
        F.out(); puts("");
    }
    return 0;
}

原文地址:https://www.cnblogs.com/Mychael/p/9039039.html

时间: 2024-10-11 09:48:30

BZOJ5300 [Cqoi2018]九连环 【dp + 高精】的相关文章

【日常学习】【区间DP+高精】codevs1166 矩阵取数游戏题解

题目来自NOIP2007TG3 如果在考场上我现在已经歇菜了吧 今天一整天的时间全部投在这道题上,收获不小. 先上题目 题目描述 Description [问题描述] 帅帅经常跟同学玩一个矩阵取数游戏:对于一个给定的n*m 的矩阵,矩阵中的每个元素aij均 为非负整数.游戏规则如下: 1. 每次取数时须从每行各取走一个元素,共n个.m次后取完矩阵所有元素: 2. 每次取走的各个元素只能是该元素所在行的行首或行尾: 3. 每次取数都有一个得分值,为每行取数的得分之和,每行取数的得分= 被取走的元素

[DP][高精][NOIP]Hanoi双塔问题

题目梗概 Hanoi塔问题的基础上,每种圆盘加了一个.实际内容并没有变化. 思考 首先来一波Hanoi问题的步数公式推导: 首先n个不同的圆盘. 只有把n-1个圆盘从a->b,最后把a上剩余的一个圆盘从a->c. 之后把b上的n-1个圆盘从b->c. 这里的两步:把n-1个圆盘从a->c,和n-1个圆盘从b->c.所需要的步骤数.实际上就是把n-1个圆盘从a移动到c的步骤数*2,因为是等价的.从a->b和从b->c移动的圆盘个数都是一样的,所以步数就是 (n-1)

【POJ】3378 Crazy Thairs(树状数组+dp+高精)

题目 传送门:QWQ 分析 题意:给个数列,求有多少五元上升组 考虑简化一下问题:如果题目求二元上升组怎么做. 仿照一下逆序对,用树状数组维护一下就ok了. 三元怎么做呢? 把二元的拓展一位就可以了,即把第三个也扔进树状数组 所以这题就渐渐明朗了: 用$ dp[i][x] $表示以$ A[x] $结尾的$ x $元上升组有多少个 那么: $ dp[i][x]=\sum_{j=1}^{i-1} dp[j][x-1] (A[j]<A[i]) $ 其中 $ dp[i][1]=1 $ 因为多了一位大的就

SCUT - 299 - Kaildls的数组划分 - dp - 高精

https://scut.online/p/299 \(dp[i][k]\) 为前 \(i\) 个数分 \(k\) 组的最大值,那么 $dp[i][k]=max_{p=1}^{i-1}{dp[p][k-1]*sum(p+1,i)} $ #include<bits/stdc++.h> using namespace std; typedef long long ll; struct BigInt { const static int mod = 10000; const static int D

POJ 1202 Family 概率,DP,高精 难度:2

http://poj.org/problem?id=1202 难度集中在输出格式上,因为输出格式所以是高精度 递推式: 血缘肯定只有从双亲传到儿子的,所以,设f,m为双亲,son为儿子,p[i][j]为i和j之间的血缘关系,p[j][i]=p[i][j] 则: p[son][f]=p[son][m]=0.5+0.5*p[f][m] 对于兄弟和其他不是双亲的节点j,则有 p[son][j]=0.5*(p[f][j]+p[m][j]) 另外:http://swerc.up.pt/2002/Data/

bzoj 3287: Mato的刷屏计划 高精水题 &amp;&amp; bzoj AC150

3287: Mato的刷屏计划 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 124  Solved: 43[Submit][Status] Description Mato同学喜欢上QQ,但是有少数傻逼总是问他一些弱智问题.Mato感到很反感,想要鄙视一下他们.他决定在QQ上刷屏,也就是发出一大堆字符.Mato的键盘上有4个键:A.B.C.D.按A就会输入一个字符,按B会把所有字符选中,按C会把选中的字符放入剪贴板,按D会插入剪贴板的内容.他的

【日常学习】【floyd传递闭包+高精】codevs1009 产生数题解

题目描述 Description 给出一个整数 n(n<10^30) 和 k 个变换规则(k<=15). 规则: 一位数可变换成另一个一位数: 规则的右部不能为零. 例如:n=234.有规则(k=2): 2-> 5 3-> 6 上面的整数 234 经过变换后可能产生出的整数为(包括原数): 234 534 264 564 共 4 种不同的产生数 问题: 给出一个整数 n 和 k 个规则. 求出: 经过任意次的变换(0次或多次),能产生出多少个不同整数. 仅要求输出个数. 输入描述 

各种高精——一入高精深似海,从此AC是路人.

1.高精简单操作 题面 https://www.luogu.org/problemnew/show/P2152 代码 https://www.luogu.org/record/show?rid=5655289 高精,GCD,stein. 即 gcd(a,b)=2*gcd(a/2,b/2); gcd(a,b)=gcd(a/2,b); gcd(a,b)=gcd(a,b/2); 再用辗转相减套个高精就好 2.高精除int 题面 https://www.luogu.org/problemnew/show

高精专题——一入高精深似海,从此AC是路人.

1.高精简单操作 题面 代码 高精,GCD,stein. 即 gcd(a,b)=2*gcd(a/2,b/2); gcd(a,b)=gcd(a/2,b); gcd(a,b)=gcd(a,b/2); 再用辗转相减套个高精就好 2.高精除int 题面 代码 高精,katalan,组合数学. 即 暴力打表观察/分析一下,易得答案为katalan数 递推显然是要T的,化简一波就好了 再套个高精,支持除非高精就行 3.高精乘高精 题面 代码 高精,DP. DP不难,高精乘高精倒是DEBUG了一晚上... 4