NOIP模拟55
T1 Skip
解题思路
正解给的是线段树维护单调栈,但是我不会。。 CDQ 维护斜率可做!!!
先得出一个朴素的 DP 方程:设 \(f_i\) 表示最后一场是 i 的最优解。
转移方程就是 \(f_i=\max\limits_{1\le j<i}\{f_j+s_i-\binom{i-j}{2}\}\)
然后考虑优化,转移 i 时,当 \(j>k\) 且 j 优于 k 当且仅当:
\]
设 \(g(x)=f_x-\dfrac{x^2+x}{2}\) 上述条件就变成了:
\]
那么我们就可以对于横坐标为数组下标,纵坐标为 \(g(x)\) 维护一个上凸包。
然后就是 CDQ 优化斜率了,注意一个点,先处理左边的子区间,然后处理当前区间,最后处理右边的子区间就好了。
由于要在队列里面保留一个元素,因此更新答案时需要判断队首元素是否合法。
code
#include<bits/stdc++.h>
#define int long long
#define ull unsigned long long
#define f() cout<<"Failed"<<endl
using namespace std;
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
return x*f;
}
const int N=1e5+10,INF=1e18;
int n,ans=-INF,f[N],q[N];
struct Node{int id,dat;}s[N];
bool comp1(Node x,Node y){return (x.dat==y.dat)?x.id<y.id:x.dat<y.dat;}
bool comp2(Node x,Node y){return x.id<y.id;}
int g(int x){return f[x]-(x*x+x)/2;}
void CDQ(int l,int r)
{
if(l==r) return f[s[l].id]=max(f[s[l].id],s[l].dat-(s[l].id-1)*s[l].id/2),void() ;
int mid=(l+r)>>1,i=l,j=mid+1,head=1,tail=0; CDQ(l,mid);
sort(s+l,s+mid+1,comp2); sort(s+mid+1,s+r+1,comp2);
while(j<=r)
if(i<=mid&&s[i].id<s[j].id)
{
while(head<tail&&(g(s[i].id)-g(s[q[tail]].id))*(s[q[tail]].id-s[q[tail-1]].id)>=(g(s[q[tail]].id)-g(s[q[tail-1]].id))*(s[i].id-s[q[tail]].id)) tail--;
q[++tail]=i; i++;
}
else
{
while(head<tail&&(g(s[q[head+1]].id)-g(s[q[head]].id))>=-s[j].id*(s[q[head+1]].id-s[q[head]].id)) head++;
if(s[q[head]].id<s[j].id) f[s[j].id]=max(f[s[j].id],g(s[q[head]].id)+s[j].dat-(s[j].id*s[j].id-2*s[j].id*s[q[head]].id-s[j].id)/2); j++;
}
sort(s+mid+1,s+r+1,comp1); CDQ(mid+1,r);
}
signed main()
{
freopen("skip.in","r",stdin); freopen("skip.out","w",stdout);
n=read(); memset(f,128,sizeof(f));
for(int i=1;i<=n;i++) s[i].id=i,s[i].dat=read();
sort(s+1,s+n+1,comp1);CDQ(1,n);
for(int i=1;i<=n;i++) ans=max(ans,f[i]-(n-i+1)*(n-i)/2);
printf("%lld",ans); return 0;
}
T2 String
解题思路
首先,有一个结论:对于 \(k>8\) 的情况,其实只要在前面输出一些 abababa...cdcdcd...efefef 就好了。
对于 \(k\le 8\) 的情况其实就是一个记忆化搜索,因为出现次数最多是 8 ,因此我们可以压位,状态就是出现次数。
然后搜索的时候对于搜过的部分小于 rk 的直接搜下去,大于等于 rk 直接返回可以减掉的排名就好了。
搜索的时候同时记录一下每种字母出现的次数以及每种总数出现的个数。
code
#include<bits/stdc++.h>
#define int long long
#define ull unsigned long long
#define f() cout<<"Failed"<<endl
using namespace std;
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
return x*f;
}
const int N=1e3+10;
int k,base,ranking,ending,cnt[N],tot[N],ch[N];
unordered_map<int,int> mp[10];
int sto(int x){if(!x)return x;return 1ll<<(4*(x-1));}
int dfs(int x,int sta,int rk,int res)
{
if(mp[res].find(sta)!=mp[res].end()&&rk>=mp[res].find(sta)->second) return mp[res].find(sta)->second;
if(sta==ending)
{
if(!rk){for(int i=1;i<x;i++) printf("%c",(char)(ch[i]+'a'));exit(0);}
return mp[res].insert(make_pair(sta,1)),1;
}
int all=0;
for(int i=base,temp;i<26;i++)
if(i!=ch[x-1])
{
ch[x]=i; cnt[i]++; tot[cnt[i]]++; temp=0;
if(tot[cnt[i]]<=k-cnt[i]+1)
temp=dfs(x+1,sta-sto(cnt[i]-1)+sto(cnt[i]),rk,cnt[i]);
all+=temp; rk-=temp; tot[cnt[i]]--; cnt[i]--;
}
return mp[res].insert(make_pair(sta,all)),all;
}
signed main()
{
freopen("string.in","r",stdin); freopen("string.out","w",stdout);
k=read(); ranking=read(); ch[0]=-1;
while(k>8)
{
for(int i=1;i<k;i++) printf("%c%c",(char)(base+'a'),(char)(base+'b'));
printf("%c",(char)(base+'a')); k-=2; base+=2;
}
for(int i=1;i<=k;i++) ending|=sto(i);
dfs(1,0,ranking-1,0); printf("-1");
return 0;
}
T3 Permutation
解题思路





code
#include<bits/stdc++.h>
#define int long long
#define ull unsigned long long
#define f() cout<<"Failed"<<endl
using namespace std;
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
return x*f;
}
const int N=5e6+10,mod=1e9+7;
int n,m,k,ans,fac[N],ifac[N];
int power(int x,int y){x%=mod;int temp=1;while(y){if(y&1)temp=temp*x%mod;x=x*x%mod;y>>=1;}return temp;}
int C(int x,int y){return fac[y]*power(fac[x]*fac[y-x],mod-2)%mod;}
signed main()
{
freopen("perm.in","r",stdin); freopen("perm.out","w",stdout);
n=read(); k=read(); m=read(); if(m==1){printf("%lld",n-k+m-1);return 0;}
fac[0]=ifac[0]=1; for(int i=1;i<=1000000;i++) fac[i]=fac[i-1]*i%mod;
ifac[n]=power(fac[n],mod-2); for(int i=n-1;i>=1;i--) ifac[i]=ifac[i+1]*(i+1)%mod;
n-=k-m;k=m; for(int i=2;i<=k;i++) ans=(ans+C(k-i+2,n-i))%mod;
for(int i=2;i<=n;i++) ans=(ans+C(k-2,n-i-1)*(i-1)%mod)%mod;
printf("%lld",ans); return 0;
}
T4 小P的生成树
解题思路
显然我们跑最小(或者最大)生成树需要的只是一个相对的大小关系。
考虑虚数在坐标轴上的表示是向量,因此就可以推出通过任意两个向量相加得出的方向当作边界,所得到的几个区间中相对大小关系都是相同的。
因此我们直接枚举这几个边界跑最大生成树并且记录 a 和 b 的和最后答案取个最大值就好了。
当然有个 \(\mathcal{O}{m^2logm}\) 的做法,但是我太菜了不会。。。
code
#include<bits/stdc++.h>
#define int long long
#define ull unsigned long long
#define f() cout<<"Failed"<<endl
using namespace std;
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
return x*f;
}
const int N=60,M=210;
const double pi=acos(-1.0);
struct Node
{
int l,r,a,b;
double len;
bool friend operator < (Node x,Node y){return x.len>y.len;}
}s[M];
int n,m,cnt,fa[N];
double ans,f[M*M*4];
int find(int x)
{
if(x==fa[x]) return x;
return fa[x]=find(fa[x]);
}
void solve(double jiao)
{
double Sa=0,Sb=0;
for(int i=1;i<=n;i++) fa[i]=i;
for(int i=1;i<=m;i++)
s[i].len=cos(jiao)*s[i].a+sin(jiao)*s[i].b;
sort(s+1,s+m+1);
for(int i=1;i<=m;i++)
{
int x=s[i].l,y=s[i].r;
if(find(x)==find(y)) continue;
fa[find(x)]=find(y);
Sa+=s[i].a; Sb+=s[i].b;
}
ans=max(ans,sqrt(Sa*Sa+Sb*Sb));
}
signed main()
{
freopen("mst.in","r",stdin); freopen("mst.out","w",stdout);
n=read(); m=read();
for(int i=1;i<=m;i++) s[i].l=read(),s[i].r=read(),s[i].a=read(),s[i].b=read();
for(int i=1;i<=m;i++)
for(int j=i+1;j<=m;j++)
{
double x=s[i].a+s[j].a,y=s[i].b+s[j].b;
f[++cnt]=acos(y/sqrt(x*x+y*y));
f[++cnt]=acos(y/sqrt(x*x+y*y))+pi;
f[++cnt]=acos(y/sqrt(x*x+y*y))+pi/2.0;
}
f[++cnt]=-pi/2.0;
for(int i=1;i<=cnt;i++) solve(f[i]);
printf("%.6lf",ans);
return 0;
}
NOIP模拟55的更多相关文章
- 2021.9.17考试总结[NOIP模拟55]
有的考试表面上自称NOIP模拟,背地里却是绍兴一中NOI模拟 吓得我直接文件打错 T1 Skip 设状态$f_i$为最后一次选$i$在$i$时的最优解.有$f_i=max_{j<i}[f_j+a ...
- Noip模拟55 2021.9.17(打表大胜利)
T1 skip 普通$dp$很好打: $f[i]=max(f[j]-\sum_{k=1}^{K}k+a_i)$ 就是要注意边界问题很烦人. 1 #include<bits/stdc++.h> ...
- CH Round #55 - Streaming #6 (NOIP模拟赛day2)
A.九九归一 题目:http://ch.ezoj.tk/contest/CH%20Round%20%2355%20-%20Streaming%20%236%20(NOIP模拟赛day2)/九九归一 题 ...
- contesthunter暑假NOIP模拟赛第一场题解
contesthunter暑假NOIP模拟赛#1题解: 第一题:杯具大派送 水题.枚举A,B的公约数即可. #include <algorithm> #include <cmath& ...
- 大家AK杯 灰天飞雁NOIP模拟赛题解/数据/标程
数据 http://files.cnblogs.com/htfy/data.zip 简要题解 桌球碰撞 纯模拟,注意一开始就在袋口和v=0的情况.v和坐标可以是小数.为保险起见最好用extended/ ...
- NOIP模拟题汇总(加厚版)
\(NOIP\)模拟题汇总(加厚版) T1 string 描述 有一个仅由 '0' 和 '1' 组成的字符串 \(A\),可以对其执行下列两个操作: 删除 \(A\)中的第一个字符: 若 \(A\)中 ...
- NOIP模拟 1
NOIP模拟1,到现在时间已经比较长了.. 那天是6.14,今天7.18了 //然鹅我看着最前边缺失的模拟1,还是终于忍不住把它补上,为了保持顺序2345重新发布了一遍.. # 用 户 名 ...
- NOIP模拟17.9.22
NOIP模拟17.9.22 前进![问题描述]数轴的原点上有一只青蛙.青蛙要跳到数轴上≥
- NOIP 模拟4 T2
本题属于二和一问题 子问题相互对称 考虑对于问题一:知a求b 那么根据b数组定义式 显然能发现问题在于如何求dis(最短路) 有很多算法可供选择 dijsktra,floyed,bfs/dfs,spf ...
- noip模拟29[简单的板子题](虽然我不会)
\(noip模拟29\;solutions\) 这次考试给我最大的伤害,让我意识到了差距 这场考试可以说是非常的简单,就是简单到,看两眼,打个表就有结果了 但是呢?我考得非常的完蛋,只有30pts 据 ...
随机推荐
- springboot 整合webservice 相关说明
1.环境依赖 jdk8, springboot 2.3.12.release,cxf版本需要根据springboot版本修改,方法:查看springboot版本的发布日期,然后根据日期找相近的两个版本 ...
- 鸿蒙HarmonyO实战-ArkUI动画(组件内转场动画)
前言 转场动画是一种在电影.视频和演示文稿中使用的动画效果,用于平滑地切换不同的场景或幻灯片.转场动画可以增加视觉吸引力,改善观众的观看体验. 常见的转场动画包括淡入淡出.滑动.旋转.放大缩小等效果. ...
- 力扣224(java)-基本计算器(困难)
题目: 给你一个字符串表达式 s ,请你实现一个基本计算器来计算并返回它的值. 注意:不允许使用任何将字符串作为数学表达式计算的内置函数,比如 eval() . 示例 1: 输入:s = " ...
- 地址标准化服务AI深度学习模型推理优化实践
简介: 深度学习已在面向自然语言处理等领域的实际业务场景中广泛落地,对它的推理性能优化成为了部署环节中重要的一环.推理性能的提升:一方面,可以充分发挥部署硬件的能力,降低用户响应时间,同时节省成本:另 ...
- 为 Serverless Devs 插上 Terraform 的翅膀,解耦代码和基础设施,实现企业级多环境部署(下)
简介: 在上篇<为 Serverless Devs 插上 Terraform 的翅膀,实现企业级多环境部署(上)>中,主要介绍了 Serverless Devs 多环境功能的使用,用户读完 ...
- dubbo-go v3 版本 go module 踩坑记
简介: 该问题源于我们想对 dubbo-go 的 module path 做一次变更,使用 dubbo.apache.org/dubbo-go/v3 替换之前的 github.com/apache/d ...
- C语言程序设计-笔记04-函数
C语言程序设计-笔记04-函数 例5-1 计算圆柱体的体积.输入圆柱的高和半径,求圆柱体积volume=πxr^2xh.要求定义和调用函数cylinder(r,h)计算圆柱体的体积. #includ ...
- 【LGR-170-Div.3】洛谷基础赛 #6 & Cfz Round 3 & Caféforces #2
这套题感觉质量很高,思维含量大概div.2? A.Battle \[x \equiv r(\bmod P) \] \[P \mid x - r \] 因此只有第一次操作是有效的. void solve ...
- Codeforces Round 917 (Div. 2)
A. Least Product 存在 \(a[i] = 0\),\(min = 0\),不需要任何操作. 负数个数为偶数(包括0),\(min = 0\),把任意一个改为 \(0\). 负数个数为奇 ...
- pde复习笔记 第一章 波动方程 第三节 分离变量法
教材 谷超豪<数学物理方程>第四版,虽然我们老师用的第三版,但是除了页码对不上,习题多了一点,也似乎没有多少区别. 打算开个新栏专门总结一下pde的各种计算问题,在图书馆算的手麻了,但是习 ...