2018.8.7 正睿暑期集训营 Day4

时间:5h(实际)

期望得分:...

实际得分:...

_(:зゝ∠)_

比赛链接

A 世界杯(贪心)

题目链接

设法国队赔率为x,克罗地亚赔率为y,则一个人会在x>=1/p时下注法国队(\(x*pi*ai\geq ai\))。

那么按1/p从小到大排序,下注法国的一定是一个前缀。同理,下注克罗地亚队的一定是一个后缀(1/(1-p))。

一个人下注相当于得到ai收益,但是可能会付 \(赔率*ai\) 的代价。当x增大时,法国赢了时代价就会变大,要让y适当增大来获得收益。

即y随x增大而增大。可以枚举x。

设投法国收益为w1,代价cost1=w1x;克罗地亚收益w2,代价cost2=w2x。

某种情况的收益是min(w1-cost2, w2-cost1),x增大w1,cost1增大,要最大化min就要增大w2,即y一定单调增大。

三分套三分套二分为什么WA呢。。

//365ms	16532kb(rank2 800+ms 学了一波double read() 233)
#include <cstdio>
#include <cctype>
#include <algorithm>
//#define gc() getchar()
#define MAXIN 400000
#define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++)
const int N=1e6+5; int n;
char IN[MAXIN],*SS=IN,*TT=IN;
struct Node
{
double a,p;
bool operator <(const Node &node)const{
return p>node.p;
}
}A[N]; inline double read()
{
double x=0,y=0.1; register char c=gc();
for(; !isdigit(c)&&c!='.'; c=gc());
for(; isdigit(c); x=x*10+c-'0',c=gc());
for(c=='.'&&(c=gc()); isdigit(c); x+=(c-'0')*y,y*=0.1,c=gc());
return x;
} int main()
{
// freopen("a.in","r",stdin);
// freopen("a.out","w",stdout); n=read();
for(int i=1; i<=n; ++i) A[i].a=read(), A[i].p=read();//scanf("%lf%lf",&A[i].a,&A[i].p);
std::sort(A+1,A+1+n); double Ans=0,s1=0,s2=A[n].a/*初始肯定有的啊(or 0)*/,x,y1,y2;
for(int i=1,j=n; i<=n; ++i)
{
s1+=A[i].a, x=1.0/A[i].p;
y1=1.0/(1-A[j].p);
while(j>1)
{
y2=1.0/(1-A[j-1].p);
if(std::min(s1-(y1-1)*s2,s2-(x-1)*s1)<std::min(s1-(y2-1)*(s2+A[j-1].a),s2+A[j-1].a-(x-1)*s1))
y1=y2, s2+=A[--j].a;
else break;
}
Ans=std::max(Ans,std::min(s1-(y1-1)*s2,s2-(x-1)*s1));
}
printf("%.6lf\n",Ans); return 0;
}

B 数组(线段树)

题目链接

暴力的话,枚举每个左端点,然后找到\(\min\{nxt_j\}-1\),加上这段区间长度。(枚举右端点,求\(max\{las_j\}+1\)也一样)

如果不考虑区间内其它数的限制(只考虑本身重复的限制),如果我们能维护每个位置上次出现的位置\(las\)(set就可以),以\(i\)为右端点的区间长度就为\(i-las+1\)。

如果是算非法区间个数的话,\(las\)就是\(i\)的答案,so直接算非法的好了(这样枚举右端点更方便些)。

现在考虑区间\([las_i,i-1]\)内其它数对\(i\)延伸距离的限制,记其中最靠右的它第二次(从右往左)出现的位置为\(right\)(就是\(\max\{las_j\}\))。

若\(right<las_i\),则答案就是\(las_i\);否则会将\(i\)拦住,\(i\)的答案就为\(right\)。

对于一个区间\(i\),答案的更新同理,只是在\(right[before\ i]<right[i]\)时,答案的更新可能分成几部分,一部分会被\(right[before\ i]\)限制,一部分其区间本身限制。递归即可。

用线段树维护。

记\(sum[rt](l,r)\)为只考虑\([l,r]\)中数的限制,右端点\(i\in [l,r]\)时它们的贡献和,\(sum[1]\)就是全局非法区间数。

复杂度\(O(n\log^2n)\)。

#include <set>
#include <cstdio>
#include <cctype>
#include <algorithm>
//#define gc() getchar()
#define MAXIN 300000
#define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++)
typedef long long LL;
const int N=1e5+5; int n,A[N],las[N],las_v[N];
std::set<int> st[N];
char IN[MAXIN],*SS=IN,*TT=IN; struct Segment_Tree
{
#define ls rt<<1
#define rs rt<<1|1
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define S N<<2
int right[S];
LL ans[S]; LL Calc(int l,int r,int rt,int Right)
{
if(l==r) return std::max(right[rt],Right);
int m=l+r>>1;
if(right[ls]<Right) return 1ll*(m-l+1)*Right+Calc(rson,Right);
return ans[rt]-ans[ls]+Calc(lson,Right);//部分左区间和整个右区间受限制,右区间此时的答案是ans[rt]-ans[ls]而不是ans[rs](rt已经限制住rs了)。
}
inline void Update(int l,int r,int m,int rt)
{//考虑左区间对右区间的限制
if(right[ls]>=right[rs]) right[rt]=right[ls], ans[rt]=ans[ls]+1ll*(r-m)*right[ls];
else right[rt]=right[rs], ans[rt]=ans[ls]+Calc(m+1,r,rs,right[ls]);
}
void Build(int l,int r,int rt)
{
if(l==r) {ans[rt]=right[rt]=las[l]; return;}
int m=l+r>>1;
Build(lson), Build(rson), Update(l,r,m,rt);
}
void Modify(int l,int r,int rt,int p,int v)
{
if(l==r) {ans[rt]=right[rt]=v; return;}
int m=l+r>>1;
if(p<=m) Modify(lson,p,v);
else Modify(rson,p,v);
Update(l,r,m,rt);
}
}T; inline int read()
{
int now=0;register char c=gc();
for(;!isdigit(c);c=gc());
for(;isdigit(c);now=now*10+c-'0',c=gc());
return now;
}
void Modify(int val,int pos)
{
static std::set<int>::iterator pre,nxt; int vp=A[pos];
pre=st[vp].lower_bound(pos), --pre;
nxt=st[vp].upper_bound(pos);
if(nxt!=st[vp].end()) T.Modify(1,n,1,*nxt,*pre);
st[vp].erase(pos); pre=nxt=st[val].upper_bound(pos), --pre;
st[val].insert(pos), T.Modify(1,n,1,pos,*pre);
if(nxt!=st[val].end()) T.Modify(1,n,1,*nxt,pos);
A[pos]=val;
} int main()
{
// freopen("b.in","r",stdin);
// freopen("my.out","w",stdout); n=read();
for(int i=1; i<=n; ++i) st[i].insert(0);
for(int i=1,a; i<=n; ++i)
a=A[i]=read(), st[a].insert(i), las[i]=las_v[a], las_v[a]=i;
T.Build(1,n,1); LL tot=1ll*n*(n+1)>>1;
for(int Q=read(); Q--; )
if(!read()) printf("%lld\n",tot-T.ans[1]);
else Modify(read(),read()); return 0;
}

C 淘汰赛

题目链接

生成函数+倍增+常系数线性递推。。


考试代码

A

#include <cstdio>
#include <algorithm>
#define INF 1e14
#define eps (1e-8)
typedef long double ld;
const int N=1e6+5;
//#define double ld
int n;
struct Node
{
double a,p;
bool operator <(const Node &x)const{
return p>x.p;
}
}A[N];
double sum[N],sum2[N],Ans,W1,C1,W2,C2; void Calc1(double x)
{
int l=1,r=n,mid,ans=0;
while(l<=r)
{
mid=l+r>>1;
if((ld)x*A[mid].p>=1) ans=mid, l=mid+1;
else r=mid-1;
}
W1=sum[ans], C1=W1-x*sum[ans];
}
void Calc2(double x)
{
int l=1,r=n,mid,ans=0;
while(l<=r)
{
mid=l+r>>1;
if((ld)x*(1-A[mid].p)>=1) ans=mid, r=mid-1;
else l=mid+1;
}
W2=sum2[ans], C2=W2-x*sum2[ans];
}
inline double Get_Ans(double x)
{
Calc2(x); Ans=std::max(Ans,std::min(C1+W2,C2+W1));
return std::min(C1+W2,C2+W1);
}
inline double Get_Ans2(double x)
{
Calc1(x);
double l=0,r=1e7,lmid,rmid;
while(r-l>eps)
{
lmid = l+(r-l)/3, rmid = r-(r-l)/3;
if(Get_Ans(lmid)>Get_Ans(rmid)) r=rmid;
else l=lmid;
}
return Get_Ans(l);
} int main()
{
// freopen("a2.in","r",stdin);
// freopen("a.out","w",stdout); scanf("%d",&n);
for(int i=1; i<=n; ++i) scanf("%lf%lf",&A[i].a,&A[i].p);
std::sort(A+1,A+1+n);
for(int i=1; i<=n; ++i) sum[i]=sum[i-1]+A[i].a;
for(int i=n; i; --i) sum2[i]=sum2[i+1]+A[i].a; double l=0,r=1e7,lmid,rmid;
while(r-l>eps)
{
lmid = l+(r-l)/3, rmid = r-(r-l)/3;
if(Get_Ans2(lmid)>Get_Ans2(rmid)) r=rmid;
else l=lmid;
}
printf("%.6lf\n",Ans); return 0;
}

B

#include <set>
#include <cstdio>
#include <cctype>
#include <algorithm>
//#define gc() getchar()
#define MAXIN 400000
#define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++)
typedef long long LL;
const int N=1e5+5; int n,A[N];
char IN[MAXIN],*SS=IN,*TT=IN; inline int read()
{
int now=0;register char c=gc();
for(;!isdigit(c);c=gc());
for(;isdigit(c);now=now*10+c-'0',c=gc());
return now;
}
namespace Subtask1
{
bool vis[N];
inline void Query()
{
vis[A[n+1]]=1;//n+1
LL res=0;
for(int i=1; i<=n; ++i)
{
int j=i;
while(!vis[A[j]]) vis[A[j++]]=1;
res+=j-i;
for(int k=i; k<j; ++k) vis[A[k]]=0;
}
printf("%lld\n",res);
}
void Main()
{
int Q=read();
for(int i=1; i<=Q; ++i)
if(!read()) Query();
else A[read()]=read();
}
}
namespace Subtask2
{
std::set<int> pos[1005];
} int main()
{
// freopen("b2.in","r",stdin);
// freopen("my.out","w",stdout); n=read();
for(int i=1; i<=n; ++i) A[i]=read();
if(n<=1000) {Subtask1::Main(); return 0;} return 0;
}

C

#include <cstdio>
#include <cassert>
#include <algorithm>
#define gc() getchar()
#define mod (998244353)
typedef long long LL;
const int N=1e6+5; LL n; int m; namespace Subtask1
{
#define N 1005
int f[N][N],ans[N][N],pw[N];
bool vis[N][N];
#undef N
int DFS(int n,int m)
{
if(!m) return n==1;
// if(n<pw[m]) return 0;
if(vis[n][m]) return ans[n][m];
LL res=0;
for(int i=pw[m-1],lim=n>>1; i<=lim; ++i)
res+=1ll*DFS(i,m-1)*f[n][i]%mod;
vis[n][m]=1;
return ans[n][m]=(int)(res%mod);
}
void Main()
{
for(int i=0; i<=m; ++i) pw[i]=1<<i;
f[2][1]=f[3][1]=1;
for(int i=4; i<=n; ++i)
for(int j=1,lim=i>>1; j<=lim; ++j)
f[i][j]=f[i-1][j]+f[i-2][j-1], f[i][j]>=mod&&(f[i][j]-=mod);
printf("%d\n",DFS(n,m));
}
} int main()
{
// freopen("c2.in","r",stdin);
// freopen(".out","w",stdout); scanf("%lld%d",&n,&m);
if(n<=1003) {Subtask1::Main(); return 0;}
putchar('0');//输出1 13分。。 return 0;
}

8.7 正睿暑期集训营 Day4的更多相关文章

  1. 8.10 正睿暑期集训营 Day7

    目录 2018.8.10 正睿暑期集训营 Day7 总结 A 花园(思路) B 归来(Tarjan 拓扑) C 机场(凸函数 点分治) 考试代码 A B C 2018.8.10 正睿暑期集训营 Day ...

  2. 8.6 正睿暑期集训营 Day3

    目录 2018.8.6 正睿暑期集训营 Day3 A 亵渎(DP) B 绕口令(KMP) C 最远点(LCT) 考试代码 A B C 2018.8.6 正睿暑期集训营 Day3 时间:5h(实际) 期 ...

  3. 8.9 正睿暑期集训营 Day6

    目录 2018.8.9 正睿暑期集训营 Day6 A 萌新拆塔(状压DP) B 奇迹暖暖 C 风花雪月(DP) 考试代码 A B C 2018.8.9 正睿暑期集训营 Day6 时间:2.5h(实际) ...

  4. 8.8 正睿暑期集训营 Day5

    目录 2018.8.8 正睿暑期集训营 Day5 总结 A 友谊巨轮(线段树 动态开点) B 璀璨光滑 C 构解巨树 考试代码 A B C 2018.8.8 正睿暑期集训营 Day5 时间:3.5h( ...

  5. 8.5 正睿暑期集训营 Day2

    目录 2018.8.5 正睿暑期集训营 Day2 总结 A.占领地区(前缀和) B.配对(组合) C 导数卷积(NTT) 考试代码 T1 T2 T3 2018.8.5 正睿暑期集训营 Day2 时间: ...

  6. 8.4 正睿暑期集训营 Day1

    目录 2018.8.4 正睿暑期集训营 Day1 A 数对子 B 逆序对 C 盖房子 考试代码 A B C 2018.8.4 正睿暑期集训营 Day1 时间:4.5h(实际) 期望得分:30+50+3 ...

  7. 7.30 正睿暑期集训营 A班训练赛

    目录 2018.7.30 正睿暑期集训营 A班训练赛 T1 A.蔡老板分果子(Hash) T2 B.蔡老板送外卖(并查集 最小生成树) T3 C.蔡老板学数学(DP NTT) 考试代码 T2 T3 2 ...

  8. 8.9 正睿暑期集训营 Day6 C 风花雪月(DP)

    题目链接 完整比赛在这儿. 杜老师tql . 求期望要抽卡的次数,也就是求期望经历了多少不满足状态.而每个不满足的状态对答案的贡献为\(1\),所以可以直接算概率.即\(Ans=\sum_{不满足状态 ...

  9. 正睿暑期培训day4考试

    链接 A 求出来到每座山的距离后,就可以计算出每只猫等待的时间与出发时间的关系. 如果出发时间为\(x\),求出来只猫的等待时间.这里用\(b_i\)表示第i只猫的等待时间.然后我们将这些时间排序.问 ...

随机推荐

  1. Java基础-配置开发环境-安装JDK

    Java基础-配置开发环境-安装JDK 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.计算机基础知识 1>.计算机的组成 计算机有硬件与软件组成. 2>.硬件: 硬 ...

  2. 怎么在sublime里面显示编码格式

    我要在sublime text里面显示编码格式 点击Preference—settings 然后再user里面加入这个 // Display file encoding in the status b ...

  3. uva 10625 Board Wrapping

    https://vjudge.net/problem/UVA-10652 给出n个长方形,用一个面积尽量小的凸多边形把他们围起来 求木板占包装面积的百分比 输入给出长方形的中心坐标,长,宽,以及长方形 ...

  4. Your Prediction Gets As Good As Your Data

    Your Prediction Gets As Good As Your Data May 5, 2015 by Kazem In the past, we have seen software en ...

  5. 基于canvas将图片转化成字符画

    字符画大家一定非常熟悉了,那么如何把一张现有的图片转成字符画呢?HTML5让这个可能变成了现实,通过canvas,可以很轻松实现这个功能.其实原理很简单:扫描图片相应位置的像素点,再计算出其灰度值,根 ...

  6. [python]python错误集锦

    ValueError: invalid literal : ''不能将非数字字符串转换为整型 object has no attribute 对象调用一个没有的方法(内建或自定义) TypeError ...

  7. 20155305乔磊2016-2017-2《Java程序设计》第六周学习总结

    20155305乔磊2016-2017-2<Java程序设计>第六周学习总结 教材学习内容总结 InputStream与OutputStream 串流设计 1.串流:Java将输入/输出抽 ...

  8. 月薪20K软件测试自动化岗必问面试题:验证码识别与处理

    本文乃Happy老师的得意门生来自java全栈自动化测试4期的小核桃所作.正所谓严师出高徒,笔下有黄金~~让我们一起来征服面试官吧~~ 在做自动化测试的时候,经常会遇到需要输入验证码的地方,有些可以让 ...

  9. __class__属性与元类

    class M(type): def __str__(self): return "gege" aa = "ccf" cc = "ccc" ...

  10. spring事务详解(二)实例

    在Spring中,事务有两种实现方式: 编程式事务管理: 编程式事务管理使用底层源码可实现更细粒度的事务控制.spring推荐使用TransactionTemplate,典型的模板模式. 申明式事务管 ...