csp-s模拟43,44 A,C,F
题面:https://www.cnblogs.com/Juve/articles/11534880.html
A:
T可以写成如下形式:$T=b^k*S+m*a$,
其中$m=\sum\limits_{i=1}^{k}p_i*b^i$
然后k最多64,所以枚举即可
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#define int long long
#define re register
using namespace std;
int s,t,a,b,ans=0x7fffffff,res,tot=0,n=1;
signed main(){
scanf("%lld%lld%lld%lld",&s,&t,&a,&b);
while(t-s*n>=0){
re int p=t-s*n;
if(p%a==0){
p/=a;
res=0;
for(re int i=tot;i>=0;--i){
int q=pow(b,i);
res+=p/q;
p%=q;
}
ans=min(res+tot,ans);
}
n*=b;
++tot;
}
printf("%lld\n",ans);
return 0;
}
C:
有一个贪心策略
对于每一个点,我们找能加热到它的加热器中右端点最大的一个,然后加热
如果没有符合的就用特殊加热器
如果扫到当前点它已经加热超过p了就跳过
然后有一个部分分算法
如果p很小,我们可以枚举特殊加热器的使用次数,提前给他们加热,然后用贪心策略解决
之后我们优化贪心
我们发现预先枚举的使用特殊加热器的次数所得到的答案具有单谷性质,所以我们可以三分
修改操作用差分和树状数组即可
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#define int long long
#define re register
using namespace std;
const int MAXN=1e5+5;
int n,m,t,p[MAXN],maxx=0,ans,g[MAXN],c[MAXN],l,r;
struct node{
int l,r;
friend bool operator < (node a,node b){
return a.l==b.l?a.r<b.r:a.l<b.l;
}
}pos[MAXN];
int lowbit(int x){
return x&-x;
}
int update(int x,int val){
while(x<=n){
c[x]+=val;
x+=lowbit(x);
}
}
int query(int x){
int res=0;
while(x>0){
res+=c[x];
x-=lowbit(x);
}
return res;
}
int check(int k){
int res=k*t;
for(int i=1;i<=n;++i) c[i]=0;
for(int i=1;i<=n;++i){
int q=query(i);
if(q+k>=p[i]) continue;
if(g[i]==0||g[i]>n){
return -0x7fffffffffffffff;
}else{
int tim=p[i]-q-k;
res+=tim;
update(i,tim);
update(g[i]+1,-tim);
}
}
return -res;
}
signed main(){
scanf("%lld%lld%lld",&n,&m,&t);
for(int i=1;i<=n;++i){
scanf("%lld",&p[i]);
maxx=max(maxx,p[i]);
}
for(int i=1;i<=m;++i)
scanf("%lld%lld",&pos[i].l,&pos[i].r);
sort(pos+1,pos+m+1);
int j=1,mx=0;
for(int i=1;i<=n;++i){
if(mx<i) mx=0;
while(j<=m&&pos[j].l<=i) mx=max(mx,pos[j++].r);
g[i]=mx;
}
l=0,r=maxx;
while(r-l>2){
int lmid=(l+r)>>1;
int rmid=lmid+1;
if(check(lmid)<=check(rmid)) l=lmid;
else r=rmid;
}
ans=min(min(-check(l),-check(r)),-check(l+1));
printf("%lld\n",ans);
return 0;
}
F:
30分dp:设f[i][j]表示前i个操作,指针一个在p[i],一个在j的最小代价
转移:
$f[i][j]=min{f[i-1][j]+abs(pos[i]-pos[i-1])}$
$f[i][pos[i-1]]=min(f[i][pos[i-1]],f[i-1][j]+abs(j-pos[i]))$
然后考虑优化
第一个式子我们可以用线段树的区间加
第二个式子我们把abs拆开,用线段树维护f[i][j]+j和f[i][j]-j的最小值
具体操作:先用线段树分别找f[i][j]+j和f[i][j]-j的最小值,比较f[i][j]+j-pos[i]和f[i][j]-j+pos[i],
然后将整个区间加上abs(pos[i]-pos[i-1]),最后将pos[i-1]处的权值修改为上面的最小值
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define int long long
#define re register
using namespace std;
const int MAXN=1e5+5;
int n,q,a,b,pos[MAXN];
struct node{
int val,min1,min2,l,r,laz;
}tr[MAXN<<2];
void pushup(int k){
tr[k].val=min(tr[k<<1].val,tr[k<<1|1].val);
tr[k].min1=min(tr[k<<1].min1,tr[k<<1|1].min1);
tr[k].min2=min(tr[k<<1].min2,tr[k<<1|1].min2);
}
void down(int k){
tr[k<<1].val+=tr[k].laz;
tr[k<<1].min1+=tr[k].laz;
tr[k<<1].min2+=tr[k].laz;
tr[k<<1].laz+=tr[k].laz;
tr[k<<1|1].val+=tr[k].laz;
tr[k<<1|1].min1+=tr[k].laz;
tr[k<<1|1].min2+=tr[k].laz;
tr[k<<1|1].laz+=tr[k].laz;
tr[k].laz=0;
}
void build(int k,int l,int r){
tr[k].l=l,tr[k].r=r;
tr[k].laz=0;
tr[k].val=tr[k].min1=tr[k].min2=0x7fffffff;
if(l==r){
tr[k].val=tr[k].min1=tr[k].min2=0x7fffffff;
if(l==a){
tr[k].val=abs(pos[1]-b);
tr[k].min1=tr[k].val-l;
tr[k].min2=tr[k].val+l;
}
if(l==b){
tr[k].val=abs(pos[1]-a);
tr[k].min1=tr[k].val-l;
tr[k].min2=tr[k].val+l;
}
return ;
}
int mid=(l+r)>>1;
build(k<<1,l,mid),build(k<<1|1,mid+1,r);
pushup(k);
}
void update(int k,int opt,int val){
int l=tr[k].l,r=tr[k].r;
if(l==r){
tr[k].val=val;
tr[k].min1=tr[k].val-tr[k].l;
tr[k].min2=tr[k].val+tr[k].l;
return ;
}
if(tr[k].laz) down(k);
int mid=(l+r)>>1;
if(opt<=mid) update(k<<1,opt,val);
else update(k<<1|1,opt,val);
pushup(k);
}
void change(int k,int opl,int opr,int val){
int l=tr[k].l,r=tr[k].r;
if(opl<=l&&r<=opr){
tr[k].val+=val;
tr[k].min1+=val;
tr[k].min2+=val;
tr[k].laz+=val;
return ;
}
if(tr[k].laz) down(k);
int mid=(l+r)>>1;
if(opl<=mid) change(k<<1,opl,opr,val);
if(opr>mid) change(k<<1|1,opl,opr,val);
pushup(k);
}
int query1(int k,int opl,int opr){
int l=tr[k].l,r=tr[k].r;
if(opl<=l&&r<=opr){
return tr[k].min1;
}
if(tr[k].laz) down(k);
int mid=(l+r)>>1,res=0x7fffffff;
if(opl<=mid) res=min(res,query1(k<<1,opl,opr));
if(opr>mid) res=min(res,query1(k<<1|1,opl,opr));
return res;
}
int query2(int k,int opl,int opr){
int l=tr[k].l,r=tr[k].r;
if(opl<=l&&r<=opr){
return tr[k].min2;
}
if(tr[k].laz) down(k);
int mid=(l+r)>>1,res=0x7fffffff;
if(opl<=mid) res=min(res,query2(k<<1,opl,opr));
if(opr>mid) res=min(res,query2(k<<1|1,opl,opr));
return res;
}
signed main(){
scanf("%lld%lld%lld%lld",&n,&q,&a,&b);
for(re int i=1;i<=q;++i) scanf("%lld",&pos[i]);
build(1,1,n);
for(int i=2;i<=q;++i){
int res=min(query1(1,1,pos[i])+pos[i],query2(1,pos[i],n)-pos[i]);
change(1,1,n,abs(pos[i]-pos[i-1]));
update(1,pos[i-1],res);
}
printf("%lld\n",tr[1].val);
return 0;
}
csp-s模拟43,44 A,C,F的更多相关文章
- csp-s模拟测试44「D·E·F」
用心出题,用脚造数据 乱搞场 1 #include<bits/stdc++.h> 2 #define re register 3 #define int long long 4 #defi ...
- Noip模拟43 2021.8.18
T1 地一体 可以树形$dp$,但考场没写出来,只打了没正确性的贪心水了$30$ 然后讲题的时候B哥讲了如何正确的贪心,喜出望外的学习了一下 不难发现 每次士兵都会直接冲到叶子节点 从深的点再返回到另 ...
- 8.18考试总结[NOIP模拟43]
又挂了$80$ 好气哦,但要保持优雅.(草 T1 地衣体 小小的贪心:每次肯定从深度较小的点向深度较大的点转移更优. 模拟一下,把边按链接点的子树最大深度排序,发现实际上只有上一个遍历到的点是对当前考 ...
- [考试反思]0916csp-s模拟测试44:可笑
出现了有史以来第一个3首杀AK啊...然而跟我没有丝毫关系 (曾经还是有一次考试差点就有那么一点关系的...) 然而反正我考得很水就是了.不是很垃圾,而是很水. 这套题是真的水... T1不会证复杂度 ...
- 2019.9.16 csp-s模拟测试44 反思总结
虽然说好像没有什么写这个的价值OAO 来了来了来写总结了,不能怨任何东西,就是自己垃圾x 开题顺序又和主流背道而驰,先一头扎进了公认最迷的T2,瞎搞两个小时头铁出来,然后T1和T3爆炸.基础很差,全靠 ...
- noip模拟43
A. 第一题 儿子遍历顺序按深度由小到大即可 B. 第二题 二分最小值,以点权作为初始距离跑最长路即可 直接用大根堆跑 \(dij\) 会 \(T\),考虑初始权值可以处理,且边权一定,用类似蚯蚓的方 ...
- NOIP模拟22「d·e·f」
T1:d 枚举. 现在都不敢随便打枚举了. 实际上我们只关注最后留下的矩阵中最小的长与宽即可. 所以我们将所有矩阵按a的降序排列. 从第\(n-m\)个开始枚举. 因为你最多拿 ...
- [考试总结]noip模拟43
这个题目出的还是很偷懒.... 第一题...第二题...第三题...四.... 好吧... 这几次考得都有些问题,似乎可能是有些疲惫,脑袋也是转不太动,考完总觉得自己是能力的问题,但是改一分钟之后会发 ...
- 模拟浏览器搜索功能(Ctrl + F)
写的匆忙,示意一下,有待完善.把以下代码复制到文本文件中,把文件扩展名改为.html就可以运行了. <html> <head> <style type="tex ...
随机推荐
- [JZOJ4665] 【GDOI2017模拟7.21】数列
题目 题目大意 给你一个数列,让你找到一个最长的连续子序列,满足在添加了至多KKK个数之后,能够变成一条公差为DDD的等差数列. 思考历程 一眼看上去似乎是一道神题-- 没有怎么花时间思考,毕竟时间都 ...
- 【JZOJ6287】扭动的树
description analysis 区间\(DP\),首先按照键值排个序,这样保证树的中序遍历就为原序列 设\(f[0][i][j]\)表示\([i..j]\)区间作为\([unknown..i ...
- Perl 标量
Perl 标量 标量是一个简单的数据单元. 标量可以是一个整数,浮点数,字符,字符串,段落或者一个完整的网页. 以下实例演示了标量的简单应用: 实例 #!/usr/bin/perl $age = 20 ...
- 【Servlet】Servlet监听器
一.Servlet监听器的概念 Servlet监听器是Servlet规范中定义的一种特殊类,用于监听ServletContext.HttpSession和ServletRequest等域对象的创建与销 ...
- 命令学习_ping
PING: ping是一个所有操作系统都支持的简单工具.我么可以利用ping来解析DNS 的A record和PTRrecord. A记录是将域名映射到IP地址,这个是ping的缺省功能, ping同 ...
- VS2010-MFC(字体和文本输出:文本输出)
转自:http://www.jizhuomi.com/software/241.html 上一节讲了CFont字体类,本节主要讲解文本输出的方法和实例. 文本输出过程 在文本输出到设备以前,我们需要确 ...
- 阿里云CentOs7上安装GitLab
一.安装 基本上可以根据官网的教程来安装:https://www.gitlab.com.cn/installation/#centos-7 只不过我们暂时没有邮件服务器,所以postfix没有安装. ...
- 如何利用开源思想开发一个SEO友好型网
如果你有一个网站需要去做SEO优化的时候,不要期望你的努力能立即得到回报.耐心等待并更正内容营销策略,最终会发现你的网站很受用户欢迎.下面就教你如何利用开源思维开发一个SEO友好型网站! 首先,你应该 ...
- Spring 泛型依赖注入(3)
BaseService<T>:有RoleService和UserService两的子类 BaseRepepositry<T>:有UserRepository和RoleRepos ...
- hadoop 环境下不知道yarn端口可以通过此命令查找
yarn jar hadoop-examples-2.6.0-mr1-cdh5.10.0.jar pi 1 30 hadoop-examples-2.6.0-mr1-cdh5.10.0.jar 此JA ...