0223模拟赛(波鱼)
happysugarlife / 「PJudge#1」 删数
题意
删除一个数的条件:为两边数的等差中项。求最后能最少剩多少数。
.
题解
注意到删除过后那两边的数的差就会 ,故把原数列差分过后把每个差分的数记作 ,其中 为一个奇数 (或者 ) ,那么我们考虑可不可以把 相同的连续段拉出来一起做。
那么直接在每段上 表示第 个位置上的数,后面系数为 一路合并最前面到哪里,那么就可以dp出转移点,两个转移点之间必然有一个数剩下来阻隔。
时间复杂度:.
考场正解:随便乱贪,无所谓,数据会出手。
代码
查看代码
#include <bits/stdc++.h>
using namespace std;
void read(int &x)
{
x=0;int Sig=1;char c=getchar();
while(!('0'<=c&&c<='9')){if(c=='-')Sig=-1;c=getchar();}
while('0'<=c&&c<='9'){x=x*10+c-'0';c=getchar();}
x*=Sig;
}
int dp[1000005],arr[1000005];
int p[1000005],q[1000005],f[1000005][31];
int Solve(int l,int r)
{
if(!p[l]) return 1;
f[l][q[l]]=l-1;
for(int i=l+1;i<=r;i++)
{
int M=q[i],pos=i-1;
while("I am an idiot.")
{
f[i][M]=pos;
if(pos<l||(!(~f[pos][M]))) break;
pos=f[pos][M]; M++;
}
}
dp[l-1]=0;
for(int i=l;i<=r;i++)
{
for(int j=0;j<=30;j++) if(~f[i][j]) dp[i]=min(dp[i],dp[f[i][j]]+1);
}
return dp[r];
}
int main() {
// freopen("sugar.in","r",stdin);
// freopen("sugar.out","w",stdout);
int T,n,Ans=1;T=1;
while(T--)
{
read(n); Ans=1;
for(int i=0;i<=n;i++) dp[i]=1e9,p[i]=q[i]=0;
for(int i=0;i<=n;i++) for(int j=0;j<=30;j++) f[i][j]=-1;
for(int i=1;i<=n;i++) read(arr[i]);
for(int i=1;i<n;i++)
{
p[i]=arr[i+1]-arr[i];
while((!(p[i]&1))&&p[i]) p[i]>>=1,q[i]++;
}
for(int l=1,r=1;l<n;l=r+1)
{
r=l;
while(r<n-1&&p[l]==p[r+1]) r++;
Ans+=Solve(l,r);
}
printf("%d\n",Ans);
}
return 0;
}
/*
出题人你会不会给部分分啊,区间DP都不给一个?????
五套题有三套不会给部分分,一套给虚空部分分
我只能流汗黄豆
注意到所有极大等差段的两端总是会保留的
所以我们只需要对每个极大等差段分别求答案
然后加起来
对每个等差段:
dp_i=dp_{\lceil i/2 \rceil} + (i is even)
就好了?
1 3 5 9
叉掉
不要太荒谬
删一次这一段的公差*2
所有公差都写作 2^k*x,x为奇数
实际上x相同的一堆连续公差应该放一起算
But How?
对每段每个位置预处理最左某个幂次可以到哪里
合并起来
那么dp的时候就以该幂次可合并的最大段为转移位置来。
*/
starwearer
题意
求长为 ,有 个逆序对且排列内置换长度在 以内的排列数量的奇偶性。
.
题解
对于排列 ,记 的排列 为 的逆。
我们注意到存在置换长度大于 的排列的逆一定与自己不一样,反之一定与自己一样。所以置换长度大于 的排列对方案数的奇偶性没有影响,因为每个排列必然有逆来抵消。
朴素 加上前缀和优化可以做到 。
dp状态是 bool
类型的也太浪费了吧,这不得开一个 bitset
?那么前缀和就变成按位异或了,时间复杂度变为
代码
查看代码
#include <bits/stdc++.h>
using namespace std;
int n,k;
bitset<8000010> Bit;
int solve(int x,int y)
{
if(!x||!y) return 1;
if(__builtin_clz(x)==__builtin_clz(y)) return 0;
if(31-__builtin_clz(x)>31-__builtin_clz(y)) return solve(x-(1<<(31-__builtin_clz(x))),y);
else return solve(x,y-(1<<(31-__builtin_clz(y))));
}
int main() {
// freopen("starwearer.in","r",stdin);
// freopen("starwearer.out","w",stdout);
scanf("%d %d",&n,&k);
for(int i=0;i<=k;i++) Bit[i]=solve(n-1,i);
for(int i=1;i<=n;i++) Bit^=(Bit<<i);
printf("%d",(int)Bit[k]);
return 0;
}
ANIME_19
这道题出题人说卖给lxl了,所以就不写了力。
格蕾家今天的饭
关键词:凸包暴力 复杂度是对的
敢写就敢过的题放 T4 哕哕哕。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
2021-02-24 「CEOI2014」 Cake 题解
2021-02-24 「CEOI2016」match 题解