GGN_2015 丢人现眼专场

GGN_2015退役后打算重新认真学习OI ,并在此记录一些学习中的心得体会。由于此部分内容主要为算法实现过程中出现的各种错误,以此丢人现眼。(温馨提示,此网页手机端体验局差,强烈建议在电脑端查看。)

退役后做题总览

调试到快死才调出来的,加了,一遍就水过的题画了删除线。(我就一人。。)下述题目均可在洛谷/vjudge/BZOJ上找到,如遇BZOJ权限题,会特殊标明,正在逐步完善题目链接。

动态规划系列

算法题目
数位DP「洛谷P2657」windy数
「洛谷P2602」ZJOI数字计数
「HDU2089」不要62
「LibreOJ10166」数字游戏
「洛谷P3413」SAC#1 - 萌数
数状数组优化DP「洛谷P1020」导弹拦截
「洛谷P1439」[模板]最长公共子序列
矩阵快速幂「洛谷P1962」斐波那契数列
插头DP「HDU1400」Mondriaan’s Dream
「HDU1693」Eat the Trees
「洛谷P5056」【模板】插头dp

图论相关

算法题目
差分约束「洛谷P1250」种树
「洛谷P1993」小K的农场
「洛谷P2294」 [HNOI2005]狡猾的商人
「洛谷P3275」 [SCOI2011]糖果
「洛谷P5960」【模板】差分约束算法
「洛谷P2474」 [SCOI2008]天平

数据结构

算法题目
主席树 洛谷P3834 【模板】可持久化线段树 2(主席树)
洛谷P1383 高级打字机
树套树洛谷P3157 [CQOI2011]动态逆序对

一些巧妙的思路整理

此栏目暂无。

每日刷题/总结记录

2020-07-20

题号题目名称
洛谷P2657[SCOI2009] windy 数
  1. python 写OI题一定要记得global
  2. 注意枚举下一位的所有可能取值时,值域不要用错位。
elif op == 1:
	tmp = 0 
	for j in range(0, self.A[x-1]): # !!! we should fill x-1 not x here !!!
		if(abs(j-v)>=2):
			tmp += self.f(x-1, 0, j)
	if(abs(self.A[x-1]-v)>=2): # !!! we should fill x-1 not x here !!!
		tmp += self.f(x-1, 1, self.A[x-1]) # same as upon
    self.dp[(x, op, v)] = tmp 

  1. 由于最高位上的值一定不是零,所以这种写法是可以的
    def solve(self, x):
        if(x == 0):
            return 1
        self.load(x)
        tmp = 0
        tmp += self.f(self.cnt, 2, 0) #here
        for i in range(1, self.A[self.cnt]):
            tmp += self.f(self.cnt, 0, i)
        tmp += self.f(self.cnt, 1, self.A[self.cnt]) # and here
        return tmp

写程序的时候,误以为,这是bug。
4. python类一定要记得self.

题号题目名称
洛谷P1962斐波那契数列
  1. c++里不要定义一个叫matrix的结构体,叫mat得了…
  2. 函数不写return各种导致神奇爆炸
mat uno(int n) {
	mat ans = {n, n};
	for(int i = 1; i <= n; i ++) {
		ans.a[i][i] = 1;	
	}
	return ans; // 我最开始的时候没写return
}
  1. 常规错法,记得开long long
题号题目名称
洛谷P2602[ZJOI2010]数字计数

疯狂调试一下午,最后终于在晚上九点调出来了。(洛谷题解里好像很少有跟我同一写法的。)

  1. 最开始的时候,这个地方忘了开long long,但是我最后是define int long long过的,那就无所谓了。
void load(long long x) { 
	/// load x into A[], forget to long long at first
    cnt = 0;
    while(x > 0) {
        A[++ cnt] = x%10;
        x /= 10; 
    }   
    memset(vis, 0x00, sizeof(vis));
}
  1. vis[x][op][v] = 1,记忆化除非超出定义域,否则不要直接返回一个值,而是要现给dp数组赋值,最后再返回dp数组中的值。下一次很可能返回未初始化的dp数组中的值。
long long f(int x, int op, int v) {
    if(vis[x][op][v])
        return dp[x][op][v];
    vis[x][op][v] = 1; /// may be i'm always for getting this
    if(x <= 1) { /// allow for x = 0 (cnt = 0)
        dp[x][op][v] = 1; /// don't write return 1 here !!! or you will WA
    }else{
...
  1. 推一个前缀的值,放错位置,填错值。
    for(int j = cnt-1; j >= 1; j --) {
        pre = pre*10 + A[j+1]; 
        /// this should be set at the first line not the last line of the loop, j+1 not j
...

2020-07-21 在学校机房

题号题目名称
洛谷P3413SAC#1 - 萌数

此题思路真心巧妙,基于连续三位的回文串判定具有充要性,但是我今天早上才调出来。

  1. A[1] 误写为A[i]
    for(int i = 0; i <= A[1]; i ++) {
        tmp += f(1, i==0?2:(i==A[1]?1:0), 10, i); /// A[1] not A[i] !!!!
        //printf("[debug] i = %d, contribute to tmp = %lld\n", i, f(1, i==0?2:(i==A[1]?1:0), 10, i));
        tmp %= p;
    }
  1. 调试结束后,忘记把输出改回正常
    printf("%lld", ((solve(R, cntR)-solve(L, cntL)+judge(L, cntL))%p+p)%p);
    //printf("%lld\n", solve(R, cntR)); /// forget to transport the output to normal
题号题目名称
HDU 2089不要62

一遍过,开心d。

题号题目名称
LibreOJ 10166数字游戏

带模运算记录余数的数位dp,一定要注意不要顺手就写dp[1]=1,因为有可能最后一位与所要求的余数不符合。另外题中说有多组数据,没看到。

 	if(x == 1) {
        dp[x][v][op][md] = v%N == md; /// not 1
    }else {
    ...
	while(scanf("%d%d%d", &a, &b, &N) && a && b && N) {
        printf("%d\n", solve(b)-solve(a-1));
        //printf("%d\n", solve(b));
        a = b = N = 0;
    }

2020-07-22 python日

这一天我一直在调试我之前用python写的迷你网络通讯工具ggntalk。c语言选手转python非常容易写错printprintf,然后我要教育自己不要乱写try不然忽略了解释器的报错很难调试。

「HDU4507」恨7不成妻暂时弃疗,昨天我调了一宿结果还是TLE,我估计我的算法没救了,改天照着题解重写吧。

2020-07-23 返校领毕业证

合影留念,下午在学校和学弟学习差分约束系统,并给学弟普及了johnson算法。

题号题目名称
洛谷P1993小K的农场

两个易错点:最短路dis值要初始化,边要开三倍空间(我就没开然后WA/RE彩色一片)。

题号题目名称
洛谷P1250种树

一遍过,开心。注意,差分约束的约束条件一定要找全,要确定使用最短路还是最长路。

2020-07-27 填报志愿费时费力

补写最近的几篇错题。

题号题目名称
洛谷P2294[HNOI2005]狡猾的商人

一遍水过,没啥细节。

题号题目名称
洛谷P3275[SCOI2011]糖果

首先要开三倍内存,不然会RE/WA。

其次,题中说每个小朋友都能分到糖,因此不能让小朋友分到的糖的数量是0。我才用的做法是建立一个超级源点,令超级源点的dis值为1,但是因为我比较zz,所以我最后统计答案是误把超级源点的dis值也统计到了答案中,因此输出比标准输出大1。

最后,spfa需要slf优化才能通过此题。(LLL是怎么优化来着??想不起来了。)

题号题目名称
洛谷P3275[SCOI2011]糖果

水题一遍过。

题号题目名称
洛谷P2474[SCOI2008]天平

多元最短路差分约束系统用来计算两个变量差的最大值和最小值。

  1. 弗洛伊德该continue就continue。
            if(i == k) continue; /// !!1
            for(int j = 1; j <= n; j ++) {
                if(i == j || j == k) continue; /// !!
  1. 不要把i写成j(常规错误)
            if(maxd[i][a] > mind[b][j] || maxd[j][a] > mind[b][i]) { / 写成mind[b][j] j should b i
                lcnt ++;
                //printf("lcnt++ : i = %d, j = %d\n", i, j);
            }
  1. dis[i][i] = 0 不初始化当然是不行的。

2020-07-31 紧张的备课时光

前天简化了ggntalk-pro,并和重伯君和HJQ大佬完成了通信调试。

昨天晚上写了一个带GUI的ggntalk-pro,感觉不错,不过重伯君很忙,我请增基大佬做了通信调试。

题号题目名称
HDU1400Mondriaan’s Dream

!!!i 和 j 写反了三次。。以后一定要注意,推公式时候用的字母,和编程时候用的字母一定要对应,不然很容易写反。

				int left = getb(S, j); /// j not i
				int up   = getb(S, j+1); /// j+1 not i+1
					T = setb(T, j, 0); /// setb(T, j, 0) not setb(T, i, 0)
					T = setb(T, j+1, 0); /// setb(T, j+1, 0) not setb(T, i+1, 0)
					if(i != n) {
						f[i][j+1][setb(S, j, 1)] += f[i][j][S]; /// setb(S, j, 1) not setb(S, i, 1)
					}
					if(j != m) {
						f[i][j+1][setb(S, j+1, 1)] += f[i][j][S]; /// setb(S, j+1, 1) not setb(S, i+1, 1)
					}
题号题目名称
HDU1693Eat the Trees
  1. 位运算忘加括号
int getb(int S, int p) {
    return (S&(1<<(p-1)))>>(p-1); /// miao not S&(1<<(p-1))>>(p-1)
}
  1. 各种智障错误:忘输入n和m,忘了用题中给出的障碍物位置。
题号题目名称
洛谷P5056【模板】插头dp

初次提交五彩斑斓,开大数组至14后红绿掺半。

一定要注意右下角的位置要特判,可以闭合回路。但一定要想到,所谓的“右下角的位置”不一定真的是「右下角的位置」,因为图中可能有障碍物,这些障碍物可能会占据最后一排靠右侧的几个位置。但是,无论障碍物如何分布,可以闭合回路的位置只能有一个。

                         if(i==xm && j==ym) { /// 忘记处理右下角的特殊情况!!!/// 右下角处理得不对!!!不一定真的是右下角
                             A[j] = A[j+1] = 0;
                             int T = pack(A, m+1);
                             if(f[i][j+1].find(T) == f[i][j+1].end())
                                 f[i][j+1][T] = 0;
                             f[i][j+1][T] += f[i][j][S];
                         }

2020-08-01 骑电动车上高速

翻vjudge时候翻到了这个:蓝书《算法竞赛入门经典-训练指南》题目一览

和andy大佬讨论了一些关于插头dp的简单问题,安利了一些最短路和线段树方面的模型。

2020-08-03 和YZB大神到三好街买电脑

acer - swift 3 ¥5600,装了个win10/ ubuntu 20.04双系统,到目前为止体验还不错(其实刚才在vim里死机了一次)。

复习了一下主席树的模板(突然发现自己代码能力没有想象中那么垃圾)

昨天完成了自制pastebin,但是就是传送文件的大小不能超过400Byte(顶个卵用。。。)

题号题目名称
洛谷P3834【模板】可持久化线段树 2(主席树)

首先,不离散化真的会MLE。尽管动态开点,还是会MLE,没有什么商量的余地。

其次,注意一些智障的细节。(离散化时A[i]误写成A[x],kth 中rch[rr]误写成lch[rr]。)

用线段树套线段树写了一下洛谷P3157 然后TLE了两个点,感觉没救了,可能常数过大吧。(2020-08-04, HJQ大佬加了个树状数组就A了此题,OTL。)

2020-08-04 备课日

题号题目名称
洛谷P1383高级打字机

最开始的时候误以为此题要做树上主席树,后来发现undo操作也可以被undo,问题似乎比我想象的要简单,这样只要一棵普普通通的主席树就可以了。

    void add(int& rt, int l, int r, int p, int v) {
        int nn = ++ ncnt;
        cpy(rt, nn);
        if(l == r) {
            val[nn] = v; /// val[nn]=v not val[rt]=v !!!!(rt may = 0)
        }else {
            int mid = (l + r)/2;
            if(p <= mid) {
                add(lch[nn], l, mid, p, v);
            }else {
                add(rch[nn], mid+1, r, p, v);
            }
        }
        rt = nn; /// remember to save
    }

注意不要修改结点rt的信息,而是修改结点nn的信息,最后将引用rt指向nn

题号题目名称
洛谷P1972[SDOI2009]HH的项链

一遍过,不过这道题的思路很不错,说实话不是我自己想出来的。倘若询问的右端点恰好是序列末端,统计不同元素的种类数,可以先找到每一种元素出现的最右位置,生成一个新数列B如果A[i]=x是元素x最后一次出现,则记B[i]=1,否则记B[i]=0,统计[L, N]的区间和即可得到该区间元素总数。

考虑到可以离线,对所有询问以询问区间有端点的下表按照从小到大排序,并按照排序顺序一次回答这些询问。将A中位置依次考虑,并不断调整B数组的内容,用树状数组维护B的前缀和即可快速应答对于区间和的询问。

题号题目名称
洛谷P3157[CQOI2011]动态逆序对

在HJQ大佬的指点下终于A掉了这道题,犯了一些常见的错误,如将i--误写为i++

具体的卡常方法如下:尽量少使用树套树,用树状数组初始化出每个位置i对逆序对数的贡献,然后在树套树上记录被删除的点,用来统计删除过程中每个位置与删除前减少的贡献,这样可以把树套树的调用次数减半。

2020-08-05 ~ 2020-08-07 出题三日

和HJQ大佬在合作下成功完成了一套很水的模拟赛,感谢HJQwQ大佬和linly大佬的鼎力相助。

一天不登陆洛谷就从绿名调回到蓝名了,虽然说我曾经是红名,但是退役后哪有不蓝的。。。

学习了一下如何用marp写ppt,但是不幸的是它的编译功能出了点问题,只能编译成html,编译成pdf貌似需要chrome打印。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值