8.7 正睿暑期集训营 Day4


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;
}

转载于:https://www.cnblogs.com/SovietPower/p/9443500.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
下面只是目标目录 ├─第1章-Shiro权限实战课程介绍 │ 1-1Shiro权限实战课程介绍.mp4 │ 1-2权限控制和初学JavaWeb处理访问权限控制.mp4 │ ├─第2章-大话权限框架核心知识ACL和RBAC │ 2-1权限框架设计之ACL和RBAC讲解.mp4 │ 2-2主流权限框架介绍和技术选型讲解.mp4 │ ├─第3章-ApacheShiro基础概念知识和架构讲解 │ 3-1Shiro核心知识之架构图交互和四大模块讲解.mp4 │ 3-2用户访问Shrio权限控制运行流程和常见概念讲解.mp4 │ ├─第4章-Springboot2.x整合ApacheShiro快速上手实战 │ 4-1SpringBoot2.x整合Shiro.mp4 │ 4-2快速上手之Shiro认证和授权流程实操上集.mp4 │ 4-3Shiro认证和授权流程和常用API梳理下集.mp4 │ ├─第5章-详细讲解ApacheShirorealm实战 │ 5-1Shiro安全数据来源之Realm讲解.mp4 │ 5-2快速上手之Shiro内置IniRealm实操.mp4 │ 5-3快速上手之Shiro内置JdbcRealm实操.mp4 │ 5-4ApacheShiro自定义Readl实战.mp4 │ 5-5深入Shiro源码解读认证授权流程.mp4 │ ├─第6章-Shiro权限认证Web案例知识点讲解 │ 6-1Shiro内置的Filter过滤器讲解.mp4 │ 6-2Shiro的Filter配置路径讲解.mp4 │ 6-3Shiro数据安全之数据加解密.mp4 │ 6-4Shiro权限控制注解和编程方式讲解.mp4 │ 6-5Shiro缓存模块讲解.mp4 │ 6-6ShiroSession模块讲解.mp4 │ ├─第7章-ApacheShiro整合SpringBoot2.x综合案例实战 │ 7-10使用ShiroLogout和加密处理.mp4 │ 7-1Shiro整合SpringBoot2.x案例实战介绍.mp4 │ 7-2基于RBAC权限控制实战之Mysql数据库设计.mp4 │ 7-3SpringBoot2.x项目框架和依赖搭建.mp4 │ 7-4案例实战之权限相关服务接口开发.mp4 │ 7-5案例实战之用户角色权限多对多关联查询SQL.mp4 │ 7-6案例实战自定义CustomRealm实战.mp4 │ 7-7项目实战之ShiroFilterFactoryBean配置实战.mp4 │ 7-8前后端分离自定义SessionManager验证.mp4 │ 7-9API权限拦截验证实战.mp4 │ ├─第8章-权限控制综合案例实战进阶 │ 8-1实战进阶之自定义ShiroFilter过滤器上集.mp4 │ 8-2实战进阶之自定义ShiroFilter过滤器下集.mp4 │ 8-3性能提升之Redis整合CacheManager.mp4 │ 8-4性能提升之Redis整合SessionManager.mp4 │ 8-5ShiroConfig常用bean类配置.mp4 │ ├─第9章-大话分布式应用的鉴权方式 │ 9-1单体应用到分布式应用下的鉴权方式介绍.mp4 │ 9-2Shiro整合SpringBoot下自定义SessionId.mp4 │ ├─第10章-Shiro课程总结 │ 10-1Apacheshiro从入门到高级实战课程总结.mp4 │ 10-2高级工程师到架构师-解决问题思路+学习方法.mp4 │ └─课件资料.zip

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值