【补】2022.7.21———HZOI【来自学长的馈赠2】几乎爆零记

WriteInFront

根据上一套题调整了难度,4道题都不是我原创,做过t2的可以做CF1305G

我谔谔

T1 随 T2 单 T3  题 T4 DP搬运工1

成绩综述

Rank: 47/49

我真的是太蒻了

 

T1

我的做法是@Kamisato_Ayaka 的魔改快速幂

十分巧妙的思路

具体看代码吧,懒了

对于:(a[]搞次方)(A+B+C)(A+B+C),就是AA+AB+AC+BA+..+CC

也就是Marija函数里那个j循环

算了,把Ayaka的博文转一下,我怕各位进不去

好 那我扔下代码走人了

T1
#include <iostream>
#include <iomanip>
#include <cstring>
#define GMY (520&1314)
#define FBI_OPENTHEDOOR(x) freopen(#x ".in", "r", stdin), freopen(#x ".out", "w", stdout);
#define ll long long
#define re register int
#define char_phi signed
#define MARK cout << "###"
#define _MARK "@@@"
#define LMARK "!!!~~~"
#define ZY " qwq "
#define _ " "
#define Endl cout << '\n'
#define MIN(x, y) (((x) < (y)) ? (x) : (y))
#define MAX(x, y) (((x) > (y)) ? (x) : (y))
#define ZHISHU 1000000005
#define MODER 1000000007
#define N 100002
#define M 1000000002
#define MOD 1002
#define mod %
using namespace std;
inline void Fastio_setup(){ios::sync_with_stdio(false);cin.tie(NULL), cout.tie(NULL);}
bool first_time;
long long n, m, Per, py, pa;
// Per:就题目输入的模数
// py、pa:分别是ys[]、ans[]的滚动数组下标
long long ans[3][N], ys[3][N];// 余数数组
inline long long ksm(long long A, long long B){
    long long res = 1;
    while(B != 0){
        if((B & 1) == 1) res = res * A mod MODER;
        B >>= 1;
        A = A * A mod MODER;
    }
    return res;
}
inline void Marija(bool marija){
    if(marija == true){// 对ans操作("res = res * a mod P")
        if(first_time == false){
            for(re i = 1 ; i <= Per-1 ; ++ i)// i从1开始是因为如果从0开始也就是他的余数就是0,计算之后还是0(),对答案没有贡献
                ans[pa][i] = ys[py][i];// 等同于原本快速幂的res = res * a mod P,第一次时res = 1,所以相当于第一次直接把a的值赋给了res
                // , cout << "remember this.   " << py << _ << i << _ << ans[pa][i] << _ << ys[py][i] << '\n';
            first_time = true;
            return ;
        }
        pa ^= 1;
        memset(ans[pa], 0, sizeof(ans[pa]));
        for(re i = 1 ; i <= Per-1 ; ++ i){
    // MARK, Endl;
            // cout << i << _ << ans[pa^1][i] << '\n';
            if(ans[pa^1][i] == 0) continue;// 0乘任何数等于0
            for(re j = 1 ; j <= Per-1 ; ++ j){
                ans[pa][i*j mod Per] = (ans[pa][i*j mod Per] + (ans[pa^1][i]*ys[py][j] mod MODER) ) mod MODER;//\
                                                ↑这个是(+=)改写成 = .. + ..
            }
        }
        /*      ①    ②            // i*j是排列组合
        
            ③     ④     ⑤
            上面就比如: 余数为5的有两个,余数为7的有三个,那么相乘之后余数为(35 mod P)的有 2*3个
        */
    }
    else{// 对余数操作(等同于原快速幂"a = a * a mod P")
        py ^= 1;
        memset(ys[py], 0, sizeof(ys[py]));
        for(re i = 1 ; i <= Per-1 ; ++ i){
            if(ys[py^1][i] == 0) continue;// 0乘任何数等于0
            for(re j = 1 ; j <= Per-1 ; ++ j){
                ys[py][i*j mod Per] = (ys[py][i*j mod Per] + (ys[py^1][i]*ys[py^1][j] mod MODER)) mod MODER;
                // cout << '\n' << '\n' << ys[py][i*j mod Per] << '\n' << '\n';
            }
        }
    }
}
inline void MuseDash(){// whpqの魔改快速幂
    long long Ber = m;// m的平方
    while(Ber != 0){
        if((Ber & 1) == 1) Marija(true);
        Ber >>= 1;
        Marija(false);
    }
    long long res(0);
    for(re i = 1 ; i <= Per-1 ; ++ i)
        res = (res + (ans[pa][i]*i mod MODER)) mod MODER;//\
                    有ans[pa][i]个为i的\
                    , cout << "res: " << res << '\n'
    // cout << "fzfm: " << res << _ << ksm(n, m) << '\n';
    cout << (res * ksm(ksm(n, m), MODER-2) mod MODER) << '\n';
}
inline void work(){
    cin >> n >> m >> Per;
    for(re i = 1, aer ; i <= n ; ++ i)
        cin >> aer, ys[py][aer] ++;// 因为a[i] < Per
        // , cout << "aer" << py << _ << aer << _ << ys[py][aer] << '\n'
    MuseDash();// Ayaka的做法就是基于快速幂的,他魔改了快速幂,但是要求使用此算法的人要十分了解快速幂算法\
                  我们的目的是求分子。但是由于sb双模数,我们必须要一个一个地加了之后再模\
                  错误: 我们想直接把a[]累加然后直接 mod P\
                  (a+b) mod P = (a mod P + b mod P) mod P\
                  而答案是: (a mod P + b mod P) mod MODER\
                  和上面那个柿子并不等同\
                  所以要用Ayaka的快速幂搞 这也是我赛时卡在的地方。
}
// #define IXINGMY
char_phi main(){
    #ifdef IXINGMY
        FBI_OPENTHEDOOR(a);
    #endif
    Fastio_setup();
    work();
    return GMY;
}

 

T2

题解参考锁先生

诶nm!又有密码

那好吧我截图搞过来

谢谢SoyTony,我就不写字啦(

T2
#include <iostream>
#include <iomanip>
#include <cstring>
#define GMY (520&1314)
#define FBI_OPENTHEDOOR(x) freopen(#x ".in", "r", stdin), freopen(#x ".out", "w", stdout);
#define ll long long
#define re register int
#define char_phi signed
#define MARK cout << "###"
#define _MARK "@@@"
#define LMARK "!!!~~~"
#define ZY " qwq "
#define _ " "
#define Endl cout << '\n'
#define MIN(x, y) (((x) < (y)) ? (x) : (y))
#define MAX(x, y) (((x) > (y)) ? (x) : (y))
#define N 100005
using namespace std;
#define int long long 
inline void Fastio_setup(){ios::sync_with_stdio(false);cin.tie(NULL), cout.tie(NULL);}
int T, n, option, star_cnt, all;
int head[N], w[N], dep[N], sz[N], a[N], b[N];
struct star{
    int v, nxt;
}e[N<<1];
inline void star_add(int u, int v){e[++ star_cnt].v=v, e[star_cnt].nxt=head[u], head[u]=star_cnt;}
inline void Clean(){star_cnt = 0; memset(head, 0, sizeof(head));}
void dfs0(int x, int fa){// get_size && get_depth
    sz[x] = a[x];
    for(re i = head[x] ; i ; i = e[i].nxt){
        if(e[i].v == fa) continue;
        dep[e[i].v] = dep[x]+1;
        dfs0(e[i].v, x);
        sz[x] += sz[e[i].v];
    }
}
void dfs1(int x, int fa){// get_b
    for(re i = head[x] ; i ; i = e[i].nxt){
        if(e[i].v == fa) continue;
        b[e[i].v] = b[x] + sz[1] - (sz[e[i].v]<<1);
        dfs1(e[i].v, x);
    }
}
void dfs2(int x, int fa){// get_all
    for(re i = head[x] ; i ; i = e[i].nxt){
        if(e[i].v == fa) continue;
        all += (b[e[i].v] - b[x]);// (sz[1] - (sz[son]<<1))
        dfs2(e[i].v, x);
    }
}
void dfs3(int x, int fa){
    for(re i = head[x] ; i ; i = e[i].nxt){
        if(e[i].v == fa) continue;
        sz[e[i].v] = ((sz[1] + b[x] - b[e[i].v]) >> 1); // b[son] = b[fa] + sz[1] - (sz[son]<<1)
        if(x != 1)
            sz[x] -= sz[e[i].v];
        dfs3(e[i].v, x);
    }
}
inline void work(){
    Clean();
    // fengwu巨佬的证明太精彩啦! SoyTony也很巨!
    // sz[1] = ∑(i=2, i<=n) sz[i]
    // b[son] = b[fa] - sz[son] + (sz[1] - sz[son])
    // so  ->  b[son] - b[fa] = sz[1] - (sz[son]<<1)
    // 等式右边累加,最后有: all = (n-1)*sz[1] - ((sz[2]+sz[3]+...+sz[n]) << 1)
    // 然后代换, all = (n-1)*sz[1] - (b[1] << 1)
    // so  ->  sz[1] = (all + (b[1]<<1)) / (n-1)
    cin >> n;
    for(re i = 1, uu, vv ; i <= n-1 ; ++ i){
        cin >> uu >> vv;
        star_add(uu, vv), star_add(vv, uu);
    }
    cin >> option;
    // switch op
    if(option == 0){
        memset(b, 0, sizeof(b));// sz不用清空 一会会更新
        for(re i = 1 ; i <= n ; ++ i)
            cin >> a[i];
        dep[1] = 0; dfs0(1, 0);
        for(re i = 1 ; i <= n ; ++ i)
            b[1] += a[i]*dep[i];
        dfs1(1, 0);
        for(re i = 1 ; i <= n ; ++ i)
            cout << b[i] << _;
        Endl;
    }
    else {
        // MARK;
        memset(sz, 0, sizeof(sz));
        for(re i = 1 ; i <= n ; ++ i)
            cin >> b[i];
        all = 0; dfs2(1, 0);// all记得清0
        // cout << "all: " << all << '\n';
        sz[1] = (all + (b[1]<<1)) / (n-1);
        dfs3(1, 0);
        for(re i = 2 ; i <= n ; ++ i)
            sz[1] -= sz[i];
        for(re i = 1 ; i <= n ; ++ i)
            cout << sz[i] << _;// 此sz非彼sz
        Endl;
    }
}
// #define IXINGMY
char_phi main(){
    #ifdef IXINGMY
        FBI_OPENTHEDOOR(a);
    #endif
    Fastio_setup();
    cin >> T;
    while(T --){
        work();
    }
    return GMY;
}

 

T3

卡特兰数。昧学

T3
 

#include <iostream>
#include <iomanip>
#define GMY (520&1314)
#define FBI_OPENTHEDOOR(x) freopen(#x ".in", "r", stdin), freopen(#x ".out", "w", stdout);
#define re register int
#define char_phi signed
#define MARK cout << "###"
#define _MARK "@@@"
#define LMARK "!!!~~~"
#define ZY " qwq "
#define _ " "
#define Endl cout << '\n'
#define MIN(x, y) (((x) < (y)) ? (x) : (y))
#define MAX(x, y) (((x) > (y)) ? (x) : (y))
#define N 100005
#define P 1000000007
#define mod %
using namespace std;
inline void Fastio_setup(){ios::sync_with_stdio(false);cin.tie(NULL), cout.tie(NULL);}
int option;
long long n, final_ans;
long long jc[N], f[N];// f[i]走了i步第i步回到起点
inline long long ksm(long long A, long long B){
    long long res(1);
    while(B != 0){
        if((B & 1) == 1) res = res * A mod P;
        B >>= 1;
        A = A * A mod P;
    }
    return res;
}
inline long long C(long long nn, long long mm){
    if(nn == 0 || mm == 0) return 1;
    return ((jc[nn] * ksm(jc[mm], P-2) mod P) * ksm(jc[nn-mm], P-2) mod P);
}
inline long long cat(long long x){return (C((x<<1), x) * ksm(x+1, P-2) mod P);}
inline void work(){
    // T3,还是看fengwu大佬的讲解
    // 感觉fengwu大佬还是很厉害的,像我这种蒟蒻根本不了解卡特兰数是啥
    cin >> n >> option;
    jc[0] = jc[1] = 1;
    for(long long i = 2 ; i <= n ; ++ i) jc[i] = jc[i-1] * i mod P;
    switch(option){
        case(0):{
            for(long long i = 0 ; i <= n ; i += 2){
                final_ans = (final_ans + ( ( C(n, i)*C(i, (i>>1)) mod P ) * C(n-i, ((n-i)>>1)) mod P) ) mod P;
            }
            break;
        }
        case(1):{
            final_ans = cat((n>>1));
            break;
        }
        case(2):{
            f[0] = 1;
            for(long long i = 2 ; i <= n ; i += 2){
                for(long long j = 2 ; j <= i ; j += 2){
                    f[i] = (f[i] + (f[i-j]*4 mod P) * cat( ((j>>1)-1) ) mod P) mod P;//\
                                     四个方向
                }
            }
            final_ans = f[n];
            break;
        }
        case(3):{
            for(long long i = 0 ; i <= n ; i += 2){// 枚举横坐标向左和向右一共走了i步 因为要回来所以向左和向右的步数要是相等的, 向上向下同理
                // MARK;
                final_ans = (final_ans + ( (C(n, i)*cat((i>>1)) mod P) * cat( ((n-i)>>1) ) mod P ) ) mod P;//\
                                        以任意比例互溶  (括号序列)卡特兰数(左右)     (上下)
                // cout << final_ans << _ << C(n, i) << _ << cat((n>>1)) << _ << cat(((n-i)>>1)) << '\n';
            }
            break;
        }
        default:{
            cout << "IXINGMY. Try to be the best." << '\n';
        }
    }
    cout << final_ans << '\n';
}
// #define IXINGMY
char_phi main(){
    #ifdef IXINGMY
        FBI_OPENTHEDOOR(a);
    #endif
    Fastio_setup();
    work();
    return GMY;
}

 

T4DP1

仔细想想好写,然而咕掉

a

a

 

posted @   char_phi  阅读(18)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示