微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Educational Codeforces Round 66 (Rated for Div. 2)

要是有题目FST了就重新写

A

签到

分享图片

#include<bits/stdc++.h>
using namespace std;
int T;
long long n,k,ans;
int main()
{
    cin>>T;
    while(T--)
    {
        cin>>n>>k,ans=0;
        while(n)
        {
            ans+=n%k;
            ans++,n/=k;
        }
        cout<<ans-1<<endl;
    }
}
View Code

B

暴力模拟,记得打标记和开long long,注意特判

分享图片

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+7;
int T,top;
char str[101];
ll ans,st[N];
int main()
{
    scanf("%d",&T);
    st[0]=1;
    while(T--)
    {
        scanf("%s",str);
        if(str[0]==a)
        {
            if(st[top]==-1)ans=-1;
            else ans+=st[top];
            if(st[top]==-1||ans>=(1ll<<32)){puts("OVERFLOW!!!");return 0;}
        }
        else if(str[0]==f)
        {
            ll x;scanf("%I64d",&x);
            if(st[top]==-1)st[top+1]=-1;
            else st[top+1]=x*st[top];
            top++;
            if(st[top]>=(1ll<<32))st[top]=-1;
        }
        else top--;
    }
    cout<<ans;
}
View Code

C

我写个O(nlogn)复杂了,实际上是签到题,我还写个二分

分享图片

#include<bits/stdc++.h>
using namespace std;
const int N=2e5+7;
int n,pos,a[N];
bool check(int d)
{
    for(int l=1,r=1;l<=n;L++)
    {
        while(r<n&&a[r+1]-a[l]<=2*d)r++;
        if(r-l+1>k){pos=a[l]+d;return 1;}
    }
    return 0;
}
int main()
{
    int T;scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d",&n,&k);
        for(int i=1;i<=n;i++)scanf("%d",&a[i]);
        int L=0,R=a[n]-a[1],mid,ans=R;
        while(L<=R)
        {
            mid=L+R>>1;
            if(check(mid))ans=mid,R=mid-1;
            else L=mid+1;
        }
        printf("%d\n",pos);
    }
}
View Code

D

发现是k段后缀和,其中[1,n]必须得选,其余[2,n]...[n,n]选最大的k段即可。

分享图片

#include<bits/stdc++.h>
using namespace std;
const int N=3e5+7;
int n,a[N];
long long ans,s[N];
int main()
{
    scanf("%d%d",&k);
    for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    if(n==1){printf("%d",a[1]);return 0;}
    for(int i=n;i;i--)s[i]=s[i+1]+a[i];
    sort(s+2,s+n+1);
    reverse(s+2,s+n+1);
    for(int i=1;i<=k;i++)ans+=s[i];
    cout<<ans;
}
View Code

E

首先求出每个位置仅用一条线段能走到哪,这个显然可以线段树覆盖(实际上排序也许,不过线段树太好想了)。然后愉快地倍增即可。

分享图片

#include<bits/stdc++.h>
#define lson l,rt<<1
#define rson mid+1,r,rt<<1|1
using namespace std;
const int N=5e5+7;
int n,m,all=5e5,lazy[N<<2],mx[N<<2],fa[N][20];
void modify(int rt,int v){lazy[rt]=max(lazy[rt],v),mx[rt]=max(mx[rt],v);}
void pushdown(int rt)
{
    if(!lazy[rt])return;
    modify(rt<<1,lazy[rt]),modify(rt<<1|1,lazy[rt]);
    lazy[rt]=0;
}
void update(int L,int R,int v,int l,int r,int rt)
{
    if(L<=l&&r<=R){modify(rt,v);return;}
    pushdown(rt);
    int mid=l+r>>1;
    if(L<=mid)update(L,R,v,lson);
    if(R>mid)update(L,rson);
    mx[rt]=max(mx[rt],mx[rt<<1|1]);
}
void query(int l,int rt)
{
    if(l==r){fa[l][0]=max(l,mx[rt]);return;}
    pushdown(rt);
    int mid=l+r>>1;
    query(lson),query(rson);
}
int main()
{
    scanf("%d%d",&m);
    for(int i=1,x,y;i<=n;i++)scanf("%d%d",&x,&y),update(x,y,0,all,1);
    query(0,1);
    for(int j=1;j<=19;j++)
    for(int i=0;i<=all;i++)
    fa[i][j]=fa[fa[i][j-1]][j-1];
    while(m--)
    {
        int x,ans=0;scanf("%d%d",&y);
        for(int i=19;~i;i--)if(fa[x][i]<y)x=fa[x][i],ans+=(1<<i);
        if(fa[x][0]<y)puts("-1");
        else printf("%d\n",ans+1);
    }
}
View Code

FG

太难了不会

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。