博客园挂了,不让粘图。

写的朴素一点。

#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. Delphi Tips

    Delphi Tips 函数篇 语法篇 函数篇 StrToDate() function StrToDate(const S: string): TDateTime; function StrToDa ...

  2. 爬虫之beautifulsoup篇之一

    一个网页的节点太多,一个个的用正则表达式去查找不方便且不灵活.BeautifulSoup将html文档转换成一个属性结构,每个节点都是python对象.这样我们就能针对每个结点进行操作.参考如下代码: ...

  3. MySQL基础(五)常见运算符

    MySQL常见运算符 运算符连接表达式中各个操作数,其作用是用来指明对操作数所进行的运算.常见的运算有数学计算.比较运算.位运算以及逻辑运算.运用运算符可以更加灵活地使用表中的数据,常见的运算符类型有 ...

  4. 使用ipython %matplotlib inline

    首先讲讲这句话的作用,matplotlib是最著名的Python图表绘制扩展库,它支持输出多种格式的图形图像,并且可以使用多种GUI界面库交互式地显示图表.使用%matplotlib命令可以将matp ...

  5. Vue-cli父子组件之间传参

    一.父传子( 先写父组件 父组件 <template> <子组件 :子组件的变量名='父组件的变量'> </子组件> //子组件的变量名前的冒号千万别丢了有和没有是 ...

  6. Mac部署hadoop3(伪分布式)

    环境信息 操作系统:macOS Mojave 10.14.6 JDK:1.8.0_211 (安装位置:/Library/Java/JavaVirtualMachines/jdk1.8.0_211.jd ...

  7. Bran的内核开发教程(bkerndev)-06 全局描述符表(GDT)

    全局描述符表(GDT)   在386平台各种保护措施中最重要的就是全局描述符表(GDT).GDT为内存的某些部分定义了基本的访问权限.我们可以使用GDT中的一个索引来生成段冲突异常, 让内核终止执行异 ...

  8. Hadoop(MapR)分布式安装及自动化脚本配置

    MapR的分布式集群安装过程还是很艰难的,远远没有计划中的简单.本人总结安装配置,由于集群有很多机器,手动每台配置是很累的,编写了一个自动化配置脚本,下面以脚本为主线叙述(脚本并不完善,后续继续完善中 ...

  9. Neo4j:图数据库GraphDB(四)Python中的操作

    本文总结下Python中如何操作Neo4j数据库,用到py2neo包,Pip install 一下. 1 连接neo4j数据库:跟其它数据库一样,操作前必须输入用户名和密码及地址连接一下. from ...

  10. ‎Cocos2d-x 学习笔记(21.1) ScrollView “甩出”效果与 deaccelerateScrolling 方法

    1. 简介 “甩出”效果是当我们快速拖动container并松开后,container继续朝原方向运动,但是渐渐减速直到停止的效果. ScrollView的onTouchEnded方法会设置Timer ...