2018.6.6青岛数学集训游记

CYW又一次去了集训,慢慢写吧,可能后续补一下里面代码模板什么的


Day0

翘了课!(划重点)来的集训,坐了下午2:00的车,结果8点半才到(火车在山东转了大半圈差评)。
下午好像学校月考,成功逃过了qwq
到了的话找小宾馆,母后大人预先找的,感觉被安排的明明白白
睡得非常早,结果错过了妹子夜里的信息(表示十分愧疚


Day1

上午考试
被虐惨了QAQ,T1是打表找规律,结果蒟蒻只打了表忘了找规律…
T2T3不是太懂,貌似都是dp

下午上课
是何中天巨佬给我们上课,前面讲题感觉有的太快了听不懂qaq

课表内容是他们给我的,但是我觉得太简单了没必要讲,所以今天的课主要是举几个有意思的例子活跃下气氛

主要讲的是汉诺塔(外加各种变形),高精度,直线分割平面

  1. 裸汉诺塔
    f [ 1 ] = 1 ; f [ 2 ] = 3 ;

    f [ n ] = 2 ( f [ n 1 ] ) + 1 = . . . = 2 n 1

    2. 只能在相邻柱移动,不能A-C直达

    f [ 1 ] = 2 ;
    移动步骤为:

    1. ( n 1 ) 个盘子 A->B , B->C
    2. n 号盘子 A->B
    3. ( n 1 ) 个盘子,C->B , B->A
    4. n 号盘子 B->C
    5. ( n 1 ) 个盘子,A->B , B->C

    考虑1 3 4号步骤,所需步数为 f [ n 1 ] ,则
    f [ n ] = 3 ( f [ n 1 ] ) + 2 = 3 n 1

    3. Alice和Bob在玩汉诺塔,需要让Alice设计初始状态和目标状态,使得移动步数最大

    e m m m m > A n C n

    4. 给定初始状态和目标状态,求步数

    考虑从无序状态至有序状态,再对称地至无序状态
    其中有序状态指盘子按顺序依次放在柱子上

int solve(int *a, int n, int t) {
    while (n && a[n] == t) n --;
    if (!n) return 0;
    int x = 6 - a[n] - t;
    return solve(a, n - 1, x) + 1 + s[n - 1];
}
int main()
{
    while (a[n] == b[n]) n --;
    int t = 6 - a[n] - b[n];
    ans = solve(a, n - 1, t) + 1 + solve(b, n - 1, t);
    ans = min(ans, solve(a, n - 1, b[n]) + 1 + s[n - 1] + 1 + solve(b, n - 1, a[n]));
}

其中 a [ ] 内的元素为1,2,3,表示珠子编号, s [ n ] 表示有序时的步数,即 2 n 1


平面相交

f [ 1 ] = 2 ;
f [ n ] = f [ n 1 ] + n = 1 + n ( n + 1 ) 2
推理:每一条直线与之前最多产生n个交点,所以多了n个平面

变形:n个 > 形划分平面?

考虑延长为两条直线,所以有3个平面合并为了一个,相当于少了2个平面
S [ N ] = f [ 2 n ] 2 n


快速幂

递归不上了,上一下非递归代码,用来卡常数

ll power(ll x, int y) {
    ll z = 1;
    while (y) {
        if (y & 1) (z *= x) %= mod;
        (x *= x) %= mod; y >>= 1;
    }
    return z;
}

高精度

老师给的板子好神啊,我没有这么写过结构体(因为太菜不敢写)
但是好像定义什么的比较奇怪,但是有的地方比较神奇,写起来方便
上板子了,不敢讲太多

struct bign {
    int n[N], l;
    bign() { memset(n, 0, sizeof(n)), l = 0; }
    void cl() { memset(n, 0, sizeof(n)), l = 0; }
    int& operator[] (int i) { return n[i]; }
    void rd() {
        scanf ("%s", sn + 1);
        int k = 1, ls = strlen(sn + 1);
        Rep(i, 1, ls) {
            n[l] += (sn[ls - i + 1] - '0') * k, k *= 10;
            if (i % 4 == 0 || i == ls) l ++, k = 1;
        }
        l --;
    }
    void pr() {
        int len = 0;
        Rep(i, 0, l) {
            int k = n[i];
            Rep(j, 1, 4) sn[++ len] = '0' + k % 10, k /= 10;
        }
        while (len > 1 && sn[len] == '0') len --;
        Dwn(i, len, 1) printf("%c", sn[i]);
        puts("");
    }
} ans, sum;
bign make(LL x) {
    bign a;
    while (x) a[a.l ++] = x % lm, x /= lm;
    if (a.l) a.l --;
    return a;
}
bign operator+ (bign a, bign b) {
    bign c = a; c.l = max(a.l, b.l);
    Rep(i, 0, c.l) {
        c[i] += b[i];
        c[i + 1] += c[i] / lm, c[i] %= lm;
    }
    while (c[c.l + 1]) c.l ++, c[c.l + 1] += c[c.l] / lm, c[c.l] %= lm;
    return c;
}
bign operator- (bign a, bign b) {
    bign c = a;
    Rep(i, 0, c.l) {
        c[i] -= b[i];
        if (c[i] < 0) c[i] += lm, c[i + 1] --;
    }
    while (c.l && !c[c.l]) c.l --;
    return c;
}
bign operator* (bign a, bign b) {
    bign c; c.l = a.l + b.l;
    Rep(i, 0, a.l) {
        Rep(j, 0, b.l) {
            c[i + j] += a[i] * b[j];
            //c[i + j + 1] += c[i + j] / lm;
            //c[i + j] %= lm;
        }
    }
    Rep(i, 0, c.l) c[i + 1] += c[i] / lm, c[i] %= lm;
    while (c[c.l + 1]) c.l ++, c[c.l + 1] += c[c.l] / lm, c[c.l] %= lm;
    return c;
}
bign operator+ (bign a, LL x) { return a + make(x); }
bign operator- (bign a, LL x) { return a - make(x); }
bign operator* (bign a, LL x) { return a * make(x); }
bign operator/ (bign a, LL b) {
    bign c; LL d = 0;
    c.l = a.l;
    Dwn(i, a.l, 0) d = d * lm + a[i], c[i] = d / b, d %= b;
    while (c.l && !c[c.l]) c.l --;
    return c;
}

今天的上课就没了

晚上自习cyw刷了几道二分,写了写博客
可能回去没时间补作业了qaq

猜你喜欢

转载自blog.csdn.net/CYW_lyr/article/details/80597058