比较悲惨的一周

来源:互联网 发布:squid 3.5 windows 编辑:程序博客网 时间:2024/04/28 19:33

这周打了两场比赛,一场是TC 701,一场是BC Round #89,最终结果都非常不理想,所以在这里总(fa)结(lao sao)一下。

TC 701

比赛前还是很有信心的,毕竟不做挂基本能涨涨rating就到红名了。一开始看题,第一题第一眼看上去是找个循环节直接做,但是思路不清晰,而且整个人都很紧张,然后就一直在想有没有什么其他规律能不能用其他做法之类的,一直看了20多分钟第一题,然后觉得再做第一题就没希望了,点开第二题,觉得不会做,好复杂,然后又点开第三题,两题都没思路,结果两边一起想,最后一题都没有做出来。rating从2050掉会18**,直接把上场涨的全掉了回来。

BC #89

一开始点开第一题,发现不会啊,好难,然后发现可以枚举公比,交上去过了pretest,然后开第二题,发现是傻逼题,码的很急,一开始过不了样例,直接打了个判断语句这里写图片描述来赋初值,交上去,又A了,然后无压力rank 1。接下来刷评论,发现第一题居然可以倒着来,然后公比还可能不是整数(虽然后来加了这个限制),但是我在想题时居然根本没有考虑过这两个东西,改了第一题 重新交,掉了100多分。然后搞第三题,一开始没有思路,后来知道每个点被操作次数的奇偶性是确定就会做了。然后开始码,不知道为什么,还是很紧张,这根本没人A啊,紧张个毛线啊,然后一交,RE,看代码,回溯时忘记退栈,再交,WA了,出个全是1的数据,居然没输出0,再看,有个地方写反了,再交,还是WA,这时候有公告说建议long double,又改成long double,再交才A了。最后hack的时候还挂了两发,程序都没看清楚hack什么啊。

最后第二题FST了,很显然在k=1的时候我的程序会萎掉,因为f的初值是0。然后就光荣的掉了rating,掉出了leader board。。这真是极惨的。
这里写图片描述

总结

(掉rating是好事,jcvb也会掉rating。。)做比赛不仅仅比拼知识,很多时候心态决定成败。比如说那场TC,假如我一开始冷静下来,考虑找循环节的程序的编码难度,而不是浪费时间想其他东西,可能整场比赛就会顺很多。其次,最后的时间,就应该选定一题,不再考虑另外一题,不需要担心假如自己另外一题会怎么办,相信自己的决定,不要贪心
然后在打代码时,把编码速度慢下来,打快几分钟赢的罚时还没你FST的代价高,所以尽量在打程序时就应该把细节写好。在打完一道题时,不要急着交,先看一遍程序,然后可以适当测试一些边角,极限,已经知道答案的数据(假如思路正确的话对拍估计没什么必要),确认无误后再提交。

最后附个SRM 701的简略题解吧。。

SRM 701

PartisanGame

暴力求前10^6的dp值。然后每个位置把他前5个位置的双方胜利情况存下来,总共2^10种不同状态,找到循环节后直接计。非常好打

#include <bits/stdc++.h>using namespace std;bool f[100005][2];int sav[1 << 10];class PartisanGame{public:    string getWinner(int n, vector<int> a, vector<int> b)    {        f[0][0] = 1,f[0][1] = 0;        for(int i = 1;i <= n;i ++)        {            f[i][0] = 1,f[i][1] = 0;            for(auto j : a)                if (i >= j) f[i][0] &= f[i - j][1];            for(auto j : b)                if (i >= j) f[i][1] |= f[i - j][0];            if (i >= 100)            {                int mask = 0;                for(int j = 1;j <= 5;j ++) mask = (mask << 1) | (f[i - j][0]);                for(int j = 1;j <= 5;j ++) mask = (mask << 1) | (f[i - j][1]);                if (sav[mask])                {                    int l = sav[mask],len = i - sav[mask],loop = max(0,(n - i) / len - 2);                    n -= len * loop;                } else sav[mask] = i;            }        }        return f[n][0] ? "Bob" : "Alice";    }};

KthStringAgain

可以观察(分析)到题目的操作相当于把一个子序列抽出来,顺序不变,剩下的东西翻转接到后面去。然后我们逐位确定答案,求方案数时dp,f[i][j]表示考虑到第i个位置,有j个位置是属于被抽出来的子序列的,最后的串和我们枚举的答案是匹配的方案数。每个位置最后具体在哪里是可以通过状态确定出来的。

#include <bits/stdc++.h>using namespace std;typedef long long ll;typedef pair<int,int> pi;typedef pair<ll,ll> pl;class KthStringAgain{public:    string ss;    ll calc(string out)    {        static ll f[55][55];        memset(f,0,sizeof f);        f[0][0] = 1;        int m = out.size(),n = ss.size();        for(int i = 0;i < n;i ++)            for(int j = 0;j <= i;j ++)                if (f[i][j])                {                    if ((j < m && ss[i] == out[j]) || j >= m)                        f[i + 1][j + 1] += f[i][j];                    int np = n - (i - j) - 1;                    if ((np < m && ss[i] == out[np]) || np >= m)                        f[i + 1][j] += f[i][j];                }        ll ans = 0;        for(int j = 0;j <= n;j ++) ans += f[n][j];        return ans;    }    string getKth(string s, long long k)    {        ss = s;        string out = "";        int n = s.length();        for(int i = 0;i < n;i ++)            for(char c = 'a';c <= 'z';c ++)            {                string bak = out;                out = out + c;                ll v = calc(out);                if (v >= k) break;                k -= v;                out = bak;            }        return out;    }};

FibonacciStringSum

首先,考虑最终的答案xayb,因为满足x+y=n,所以可以变成

xayb=xa(nx)b=i=0b(bi)ni(1)bixa+bi

所以只要我们求出x0...xa+b就好了。考虑dp,设f[i][0][j]表示i这个位置放的是0xj是多少,f[i][1][j]表示这个位置放的是1。那么显然,因为放1不影响答案,而且不能有两个1相邻,所以f[i][1][j]=f[i1][0][j],那么对于f[i][0][j],因为(x+1)j=jk=0(jk)xk,所以
f[i][0][j]=k=0j(jk)(f[i1][0][k]+f[i1][1][k])

很显然,f的转移可以写成矩阵的形式,那么矩阵就是(250)(250)=100100的了,毫无压力,矩阵乘法快速幂。

#include <bits/stdc++.h>using namespace std;const int mo = int(1e9) + 7;struct mat{    int a[105][105],n;    int* operator[](int x)    {        return a[x];    }    void init()    {        n = 102;        memset(a,0,sizeof a);    }    void set_I()    {        for(int i = 0;i < n;i ++) a[i][i] = 1;    }};mat operator *(mat &a,mat &b){    mat tmp;    tmp.init();    for(int i = 0;i < a.n;i ++)        for(int k = 0;k < a.n;k ++)            if (a[i][k])                for(int j = 0;j < a.n;j ++)                    if (b[k][j])                        tmp[i][j] = (tmp[i][j] + a[i][k] * 1ll * b[k][j]) % mo;    return tmp;}int c[55][55];class FibonacciStringSum{public:    mat trans,fir;    int get(int n,int a,int b)    {        for(int i = 0;i <= 50;i ++)        {            c[i][0] = 1;            for(int j = 1;j <= i;j ++)                c[i][j] = (c[i - 1][j - 1] + c[i - 1][j]) % mo;        }        trans.init(),fir.init();        for(int i = 0;i <= 50;i ++)        {            trans[i][i + 51] = 1;            for(int j = 0;j <= i;j ++)                trans[j][i] = c[i][j],trans[j + 51][i] = c[i][j];        }        fir[0][0] = 1;        int bn = n;        for(;n;n >>= 1)        {            if (n & 1) fir = fir * trans;            trans = trans * trans;        }        int ans = 0;        for(int i = 0,coef = 1;i <= b;i ++,coef = coef * 1ll * bn % mo)        {            int v = (fir[0][b - i + a] + fir[0][b - i + a + 51]) % mo;            v = v * 1ll * coef % mo * c[b][i] % mo;            if ((b - i) & 1) v = (mo - v) % mo;            ans = (ans + v) % mo;        }        return ans;    }};
2 0
原创粉丝点击