博客园挂了,不让粘图。

写的朴素一点。

#1:100+100+25=225

#2:100+70+35=205

#2:100+60+45=205(我)

回到第一机房还算不错的第一仗。

考完之后我以为我AK了然而T2被卡常打成暴力,T3贪心伪证了(虽说是全场最高分)

全程在思考。很好啊。

继续保持。

注意常数,在卡常题上要花些时间优化打法卡常。

T1:Simple

做法比较傻逼。

互质下才好做,所以把nm都干掉gcd,把这样贡献的答案先算上。

我们考虑列出一个表,每n个一行(n<=m)。

这样如果某一个数是m的倍数,那么从这里开始这一列就不会出现坏数了。

那么只要每一列算最早什么时候会出现m的倍数就好了,ex_gcd。

 #include<cstdio>
#include<iostream>
using namespace std;
#define int long long
int gcd(int a,int b){return b?gcd(b,a%b):a;}
void ex_gcd(int a,int b,int &x,int &y){
if(!b){x=;y=;return;}
ex_gcd(b,a%b,x,y);
int r=x;x=y;y=r-a/b*y;
}
main(){//freopen("ex_simple2.in","r",stdin);
int t;scanf("%lld",&t);
while(t--){
int n,m,q,ans=,x,y,g;
scanf("%lld%lld%lld",&n,&m,&q);
if(n>m)n^=m^=n^=m;
g=gcd(n,m);ans+=q-q/g;
n/=g;m/=g;q/=g;
ex_gcd(n,m,x,y);x%=m;//printf("x=%lld\n",x);
for(int i=;i<n;++i)ans+=min(((m-i)*x%m+m)%m,(q-i+n)/n);//,printf("%lld\n",ans);
printf("%lld\n",ans);
}
}

T2:Walk

卡常题。

1000000的w以内最多有240个约数,所以做dp找每个约数的最长链就好了。

 //1000000以内每个数最多有240个约数,而平均只有14个
//注意卡内存:61079552个int
#include<cstdio>
#include<iostream>
#include<unordered_map>
using namespace std;
int FIR[],L[],TO[],CNT;
void add(int a,int d){L[++CNT]=FIR[a];FIR[a]=CNT;TO[CNT]=d;}
int fir[],l[],to[],w[],cnt;
void link(int a,int b,int v){l[++cnt]=fir[a];fir[a]=cnt;to[cnt]=b;w[cnt]=v;}
int ans[],n;
unordered_map<int,int>dp[];
int read(){
register int p=;register char ch=getchar();
while(ch<''||ch>'')ch=getchar();
while(ch>=''&&ch<='')p=(p<<)+(p<<)+ch-,ch=getchar();
return p;
}
void dfs(int p,int fa){
for(int i=fir[p];i;i=l[i])if(to[i]!=fa){
dfs(to[i],p);
for(int j=FIR[w[i]];j;j=L[j]){
int x=dp[to[i]][TO[j]],y=dp[p][TO[j]];
ans[x+y+]=max(ans[x+y+],TO[j]);
dp[p][TO[j]]=max(y,x+);
}
dp[to[i]].clear();
}
}
int main(){//freopen("t2.in","r",stdin);freopen("my.out","w",stdout);
n=read();int mx=;
for(int x,y,w,i=;i<n;++i)x=read(),y=read(),w=read(),link(x,y,w),link(y,x,w),mx=max(mx,w);
for(int i=;i<=mx;++i)for(int j=i;j<=mx;j+=i)add(j,i);
dfs(,);
for(int i=n;i;--i)ans[i]=max(ans[i],ans[i+]);
for(int i=;i<=n;++i)printf("%d\n",ans[i]);
}

然后就T成暴力了。

改为对于每个约数建边,根号硬筛而不是预处理,就A了。

 #include<cstdio>
#include<iostream>
#include<vector>
using namespace std;
vector<int>a[],b[];
int fir[],l[],to[],cnt;
void link(int a,int b){l[++cnt]=fir[a];fir[a]=cnt;to[cnt]=b;}
int ans[],lgst;
int read(){
register int p=;register char ch=getchar();
while(ch<''||ch>'')ch=getchar();
while(ch>=''&&ch<='')p=(p<<)+(p<<)+ch-,ch=getchar();
return p;
}
int dfs(int p,int fa){
int mx=;
for(int i=fir[p];i;i=l[i])if(to[i]!=fa){
int x=dfs(to[i],p)+;
lgst=max(lgst,mx+x);mx=max(mx,x);
}fir[p]=;return mx;
}
int main(){//freopen("ex_walk2.in","r",stdin);freopen("my.out","w",stdout);
register int n=read();
for(int t=,x,y,w;t<n;++t){
x=read(),y=read(),w=read();
for(int i=;i*i<=w;++i)if(w%i==){
a[i].push_back(x),b[i].push_back(y);
if(i*i!=w)a[w/i].push_back(x),b[w/i].push_back(y);
}
}
for(int i=;i<=;++i){
for(int j=;j<a[i].size();++j)link(a[i][j],b[i][j]),link(b[i][j],a[i][j]);
for(int j=;j<a[i].size();++j)if(fir[a[i][j]])dfs(a[i][j],);
ans[lgst]=max(ans[lgst],i);
cnt=lgst=;
}
for(int i=n;i;--i)ans[i]=max(ans[i],ans[i+]);
for(int i=;i<=n;++i)printf("%d\n",ans[i]);
}

T3:Travel

思路懂了,还想到了优化。

但是下午就要考试显然没时间改了。

upd:所以新一场的T3还是不可改。

但是这道题至少也是想了大半个上午了好歹记一下思路。

口胡预警

我们考虑,如果L<=s-1那么向左走到头再向右是最优决策的备选方案。

另一种决策就是先向右走到头,再向左走到头,再向右走一段直到用尽向右的步数。

具体怎么算先不说,先考虑另一半情况L>s-1。

那么n-L-1<n-s。可以发现n-L-1就是向右的步数,n-s就是右边还有几个位置。

在把序列翻转之后和上面是完全等价的。这两个不等式至少满足其一。

所以如果满足L<=s-1就把序列翻转。那么决策就只有右左和左右左这两种决策了。

这就减少了很多的分类讨论量,代码应该会简洁一些。

右左的答案好说,就是2x[n]-x[1]-x[s]。方案也不难构造,两三个for循环即可。

而左右左的话,我们要从s+1开始枚举终点e。这样的话s左边和e右边都可以消耗等同于长度的向左步数。代价是长度的2倍。

而s和e之间的一段我们要耗尽剩下的向左步数。从中选出最短的几段来消耗左步数,代价为3倍,其它的代价为1倍。

终点每右移1位,你可以选的线段就多了1个,需要选的线段就多了2个。

故不存在反悔。开一个堆维护即可。

其实没必要在这时候就尝试构造方案,你找到最优的终点之后构造其实就简单了。

但是细节还是比较多,代码还是比较麻烦。

所以代码先咕了。

upd1012:咕了4天总算A掉了!开心

 #include<cstdio>
#include<queue>
using namespace std;
int n,L,s,to[],alt[],rev;long long x[],ans,y[];
int main(){//freopen("travel6.in","r",stdin);freopen("my.out","w",stdout);
scanf("%d%d%d",&n,&L,&s);
for(int i=;i<=n;++i)scanf("%lld",&x[i]);
if(L==&&s!=){puts("-1");return ;}
if(L==n-&&s!=n){puts("-1");return ;}
if(L<s-){
int mx=x[n];
for(int i=;i<=n;++i)y[i]=mx-x[n-i+];
for(int i=;i<=n;++i)x[i]=y[i];
L=n--L;s=n+-s;rev=;
}//全部转化为右左或左右左
priority_queue<int,vector<int>,greater<int> >q;
long long alc=,ans1=*x[n]-x[]-x[s],ans2=*(x[n]-x[]),E,ans=*(x[n]-x[]);
for(int e=s+;e<=n;++e){
ans-=x[e]-x[e-];
while(alc<L-(s-+n-e))ans+=q.top()*,alc++,q.pop();
q.push(x[e+]-x[e]);
if(ans<ans2)ans2=ans,E=e;
}
if(ans1<ans2){int R=n--L;printf("%lld\n",ans1);
for(int i=s+;i<=s+R-;++i)printf("%d ",rev?n-i+:i);
for(int i=n;i>=s+R;--i)printf("%d ",rev?n-i+:i);
for(int i=s-;i;--i)printf("%d ",rev?n-i+:i);
}else{printf("%lld\n",ans2);
priority_queue<pair<int,int>,vector<pair<int,int> >,greater<pair<int,int> > >q;
for(int i=s+;i<=E;++i)q.push(make_pair(x[i]-x[i-],i));
if(E!=n)L--;alt[s]=;
int pos=s;while(L>&&pos>)to[pos]=pos-,alt[pos-]=,pos--,L--;
if(pos!=)to[pos]=,alt[]=;
pos=n;if(E!=n)L++;while(L&&pos>E)to[pos]=pos-,alt[pos-]=,pos--,L--;
while(L)to[q.top().second]=q.top().second-,alt[q.top().second-]=,L--,q.pop();
for(int i=;i<=n;++i)if(!to[i])for(int j=i+;;++j)if(!alt[j]){to[i]=j;alt[j]=;break;}
//for(int i=n;i;--i)printf("%d\n",rev?n-to[i]+1:to[i]);return 0;
for(int i=to[s];;i=to[i]){printf("%d ",rev?n-i+:i);if(i==E)return ;}
}
}

[考试反思]1008csp-s模拟测试65:突袭的更多相关文章

  1. [考试反思]0718 NOIP模拟测试5

    最后一个是我...rank#11 rank#1和rank#2被外校大佬包揽了. 啊...考的太烂说话底气不足... 我考场上在干些什么啊!!! 20分钟“切”掉T2,又27分钟“切”掉T1 切什么切, ...

  2. [考试反思]0814NOIP模拟测试21

    前两名是外校的240.220.kx和skyh拿到了190的[暴力打满]的好成绩. 我第5是170分,然而160分就是第19了. 在前一晚上刚刚爆炸完毕后,心态格外平稳. 想想前一天晚上的挣扎: 啊啊啊 ...

  3. [考试反思]1109csp-s模拟测试106:撞词

    (撞哈希了用了模拟测试28的词,所以这次就叫撞词吧) 蓝色的0... 蓝色的0... 都该联赛了还能CE呢... 考试结束前15分钟左右,期望得分300 然后对拍发现T2伪了写了一个能拿90分的垃圾随 ...

  4. [考试反思]0909csp-s模拟测试41:反典

    说在前面:我是反面典型!!!不要学我!!! 说在前面:向rank1某脸学习,不管是什么题都在考试反思后面稍微写一下题解. 这次是真的真的运气好... 这次知识点上还可以,但是答题策略出了问题... 幸 ...

  5. [考试反思]0729NOIP模拟测试10

    安度因:哇哦. 安度因:谢谢你. 第三个rank1不知为什么就来了.迷之二连?也不知道哪里来的rp 连续两次考试数学都占了比较大的比重,所以我非常幸运的得以发挥我的优势(也许是优势吧,反正数学里基本没 ...

  6. [考试反思]0725NOIP模拟测试8

    看清你是个什么东西了么? 现在看清了么?rank#15?垃圾玩意? 你什么也不是.你没有骄傲,偷懒的资格! 节节败退,永无止境,你想掉到什么样子? 你还在为了成功拿到送分的T1而沾沾自喜?只不过是勉强 ...

  7. [考试反思]0714/0716,NOIP模拟测试3/4

    这几天时间比较紧啊(其实只是我效率有点低我在考虑要不要坐到后面去吹空调) 但是不管怎么说,考试反思还是要写的吧. 第三次考试反思没写总感觉缺了点什么,但是题都刷不完... 一进图论看他们刷题好快啊为什 ...

  8. [考试反思]1003csp-s模拟测试58:沉淀

    稳住阵脚. 还可以. 至少想拿到的分都拿到了,最后一题的确因为不会按秩合并和线段树分治而想不出来. 对拍了,暴力都拍了.挺稳的. 但是其实也有波折,险些被卡内存. 如果内存使用不连续或申请的内存全部使 ...

  9. [考试反思]0816NOIP模拟测试23

    210 210 210 170 还可以.暴力打满就rk4了? 但不管怎么说,总算是在改完题之后理直气壮的写考试反思了. T1是个dp,说水也不太水.(当然某脸只要A掉了一道题就要说那是水题) 我的思路 ...

随机推荐

  1. Kafka 学习笔记之 Consumer API

    Kafka提供了两种Consumer API High Level Consumer API Low Level Consumer API(Kafka诡异的称之为Simple Consumer API ...

  2. Ubuntu server 安装及jdk+mysql安装教程

    Ubuntu server 安装教程 1.查找及下载Ubuntu镜像文件 可以在以下页面下载想要的版本,我这里选择19.04 server版的iso镜像文件: http://mirrors.163.c ...

  3. Java入门之File类和IO流

    1.File类 java.io.File 类是文件和目录路径名的抽象表示,主要用于文件和目录的创建.查找和删除等操作 . 构造方法: public File(String pathname) :通过将 ...

  4. Aria2 1.35.0,更新,测试,发布

    在上一篇: 有哪些便宜还好用的东西,买了就感觉得了宝一样? 结尾提到了Tatsuhiro Tsujikawa的aria2计划在10月更新一个新的版本 今天趁着雨后明月挂天,开始了简单的更新 虽然在半年 ...

  5. oracle表空间不足:ORA-01653: unable to extend table

    问题背景: oracle表空间不足报错是比较常见的故障,尤其是没有对剩余表空间做定期巡检的系统: 报错代码如下: oracle表空间不足错误代码:ORA-01653: unable to extend ...

  6. 【TencentOS tiny】深度源码分析(7)——事件

    引言 大家在裸机编程中很可能经常用到flag这种变量,用来标志一下某个事件的发生,然后在循环中判断这些标志是否发生,如果是等待多个事件的话,还可能会if((xxx_flag)&&(xx ...

  7. Springboot2.x + ShardingSphere 实现分库分表

    之前一篇文章中我们讲了基于Mysql8的读写分离(文末有链接),这次来说说分库分表的实现过程. 概念解析 垂直分片 按照业务拆分的方式称为垂直分片,又称为纵向拆分,它的核心理念是专库专用. 在拆分之前 ...

  8. CSS中的各种单位

    单位 描述                                                                                               ...

  9. 如何让excel文件读取变得更简单

    今天给大家安利一款excel文件导入神器,easyexcel,官方地址:(https://github.com/alibaba/easyexcel). 在官网文档中有介绍了其性能. 从上面的性能测试可 ...

  10. springboot 快速开发的定制补充

    增强 SpringBoot 快速开发工具 项目地址:https://gitee.com/sanri/web-ui 优点:这是一个 web 通用配置的组件,即插即用,可用于新项目或私活.是对 Sprin ...