2019.08.07【NOIP提高组】模拟 A 组

今天的比赛做的不好,T1很简单,但是我竟然没有想到。

 

T1:首先,对于f[1…n-1]=1的做法十分显然,直接矩乘就可以了。

然后,对于这一道题,我们发现最终的f[n]一定是由f[1]、f[2]……f[k]的某个次幂分别乘起来的,那么我们就可以分开处理每一个f[i]的最终指数,具体做法和上面一样。

 

总结:1、重申一遍:这种n很大k很小的题一般就是矩乘。就算一下子推不出来矩阵也不要紧,慢慢想一想。

2、C++在定义mod的时候,用define或者const会使你的程序快很多。

 

T2:贪心即可。

把所有的区间按l从小到大排序,然后对于每一个点,把l在它之前的区间的r都扔进一个堆里,然后每次删除不合法的r,删完时候如果堆不为空,那么就取出堆顶的r与当前点匹配。这样贪心下去的结果可以保证是对的。

 

T3:这题类似以前一道做过的题,但是我竟然没有记起来。

首先我们处理出dfs序,然后对于一对u、v限制,若u、v不为祖先关系,那么dfn[u]~dfn[u]+size[u]-1这段区间和dfn[v]~dfn[v]+size[v]-1这段区间是不能组合的,若他们是祖先关系,那么就要处理出fa到son的第一个儿子(具体推一下即可)。

然后我们就可以得到很多组不能组合的点对,最终我们要求可以组合的方案数,这个就是一个简单的扫描线操作。

 

总结:在这里说一下这种被覆盖多次的点对最终答案的贡献只有1的扫描线问题怎么做。

其实核心就是要明白对于一个矩阵加1和-1时所要用到线段树上的区间是一样的。

然后我们就可以对于线段树上的每一个区间,记录下它被覆盖的次数和它的答案。若覆盖次数>=1,那么答案就是r-l+1,否则答案就等于左儿子的答案加上右儿子的答案。在修改时只需修改当前区间的被覆盖次数就可以了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值