Codeforces Round #804 (Div. 2)
https://vjudge.net/contest/504582#problem/C
T3
找规律
【归纳】大化小思想
当整体构造的方案不好考虑,我考虑每一个数的合法位置可能出现在哪
主动有序
一个位置一个位置放,肯定不好想,我就从0是mx开始考虑,一直考虑到k是mx
这样结果就是可控制的了
按照0----n-1的顺序拓展区间
考虑每个数可以放在哪个位置
当拓展到k数,当前区间是l r
如果k在l r的区间里面
那无论k在哪个位置都是一样的,因为一定是排到了0----k
下一个是k+1
这个数字和我刚刚加进去的k就没什么关系了(反正都在里面)
如果k不在L r
那k的位置一定是固定的在ps【k】的位置,一旦改变就和a不相似
int ps[100000+10]; int t; int main() { // freopen("a.in","r",stdin); // freopen("a.out","w",stdout); t=re(); while(t--) { int n=re(); int x; _f(i,1,n) { x=re();ps[x]=i; } int l=ps[0],r=ps[0],ans=1; _f(i,1,n-1) { if(l>ps[i])l=ps[i]; else if(ps[i]>r)r=ps[i]; else ans=(1LL*ans*(r-l+1-i))%MOD; } chu("%d\n",ans); } return 0; } /* 看起来很easy 5 5 4 0 3 2 1 1 0 4 0 1 2 3 6 1 2 4 0 5 3 8 1 3 7 2 5 0 6 4 */
T4
技巧性:
使用map的时候,如果是结构体要自定义<比较函数
不然会报错
知识性:
1.摩尔投票法
https://wenku.baidu.com/view/eb82fb79383567ec102de2bd960590c69ec3d8bc.html
时间复杂度O(1)
空间复杂度O(1)
求区间众数
思想,每次从数列中拿出两个不同的数字
最后剩下的一定是众数
这种思想和实现过程很好
就是我用cot记录当前模拟众数(mode)出现次数(相对的)
如果现在的数是mode就cot++
如果不是,cot--
如果cot==0,mode=当前数
同样的方法也可以应用于求区间中出现次数>[n/3]的数个数
开两个变量就行
2.
DP:dp[i]
(1)当我从前往后确定到pos位置,那么后面的更新不需要考虑pos前面的(无后效性)
(2)阶段i:当前i位置,把ai[i]作为连续内容,最多连续的个数
决策j:从哪个j转移
需要判断{l,r}区间能否全部删除:
用区间求众数的方法,动态维护
思路纠正
1.刚开始开了一个map映射区间,但是5000*5000容器会炸
那么就要想到dp的过程和找众数和个数的过程其实是类似的
可以合在一起,直接算
2.关于怎么找正确答案,直接开一个f[n+1]
更新的时候更新n+1,就可以考虑到结尾全部的情况
记得ans-1,最后那个数不算
这也是一个很常用的思想,主动虚拟:
use:(1)差分约束:从(0)连接所有点
(2)DP转换
const int N=2000+100,MOD=1e9+7; int ai[50000+10],f[50000+10]; int siz[50000+10];//最多会放进去50000*50000个元素,肯定会MLE int cot; int main() { // freopen("a.in","r",stdin); // freopen("a.out","w",stdout); int t=re();int n=0; while(t--) { _f(i,0,n+1)f[i]=0; n=re(); _f(i,1,n)ai[i]=re(); cot=0; _f(i,1,n+1)siz[i]=0; f[1]=1;//1前面一定可以转移呀 _f(i,1,n) { siz[ai[i]]++; cot=max(siz[ai[i]],cot); if((i&1)==0 && cot<=(i>>1))f[i+1]=1; } _f(i,1,n+1)//固定 { _f(ol,1,n+1)siz[ol]=0; siz[ai[i]]++; cot=1;//i-1 --> j+1 if(!f[i-1])continue;//说明1--i-3根本删除不了,i-1就无从转移 //chu("%d(i)can be update\n",i); if((i==(n+1))||ai[i-1]==ai[i])f[i]=max(f[i],f[i-1]+1); // chu("%d-->%d:f:%d\n",i-1,i,f[i]); _f(j,i+1,n) { // chu("update:%d--%d\n",i-1,j+1); cot=max(++siz[ai[j]],cot); //chu("max num:%d\n",cot); if(((j+1==n+1)||(ai[i-1]==ai[j+1]))&&cot<=((j-i+1)>>1)&&((j-i+1)&1)==0) { f[j+1]=max(f[i-1]+1,f[j+1]); // chu("%d-->%d:f:%d\n",i-1,j+1,f[j+1]); } } } chu("%d\n",f[n+1]-1); } return 0; }
T5