『模拟赛』CSP-S加赛1

Rank

一般

image

A. 小W与伙伴招募

仔细想了想,发现是贪心题。

赛时想了跟正解完全有些不太一样的做法,被顶针说假了,但其实开了 long long 能有 80pts。后来发现如果思路正确打 \(\mathcal{O(nm)}\) 的暴力能有 95pts。

《对于 60% 的数据》

考虑正解的贪法,每天相当于将第 \(i\) 宝石进货 \(b_i\) 个,维护一下每种宝石当前库存,然后从小到大买即可,这样也就有了上面 \(\mathcal{O(nm)}\) 的做法。要想过最后一个点,我们可以考虑输出前缀和 我们考虑用线段树来维护这个库存,线段树上二分来解决查询,这样就做到了 \(\mathcal{O(n\log m+m)}\) 的复杂度。还有一种单调栈优化的,能达到 \(\mathcal{O(n)}\),比较牛。

点击查看代码
#include<bits/stdc++.h>
#define fo(x,y,z) for(register ll (x)((y));(x)<=(z);(x)++)
#define fu(x,y,z) for(register ll (x)((y));(x)>=(z);(x)--)
using namespace std;
typedef __int128 ll;
#define lx ll
inline lx qr()
{
	char ch=getchar();lx x=0,f=1;
	for(;ch<'0'||ch>'9';ch=getchar()) if(ch=='-') f=-1;
	for(;ch>='0'&&ch<='9';ch=getchar()) x=(x<<3)+(x<<1)+(ch^48);
	return x*f;
}
#undef lx
#define qr qr()
const int Ratio=0;
const int N=2e5+5;
const int mod=1e9+9;
int n,m;
int c[N];
long long ans;
ll numb[N],sumcos[N];
ll num[N<<2],sum[N<<2],tag[N<<2],cle[N<<2];
struct rmm
{
    ll a,b;
}b[N];
bool cmp(rmm A,rmm B)
{
    if(A.a!=B.a) return A.a<B.a;
    return A.b>B.b;
}
namespace Wisadel
{
    #define ls (rt<<1)
    #define rs (rt<<1|1)
    #define mid ((l+r)>>1)
    void Wpushup(int rt)
    {
        num[rt]=num[ls]+num[rs];
        sum[rt]=sum[ls]+sum[rs];
    }
    void Wpushdown(int rt,int l,int r)
    {
        num[ls]+=tag[rt]*(numb[mid]-numb[l-1]);
        num[rs]+=tag[rt]*(numb[r]-numb[mid]);
        sum[ls]+=tag[rt]*(sumcos[mid]-sumcos[l-1]);
        sum[rs]+=tag[rt]*(sumcos[r]-sumcos[mid]);
        tag[ls]+=tag[rt],tag[rs]+=tag[rt];
        tag[rt]=0;
    }
    void Wclerr(int rt)
    {
        num[ls]=num[rs]=0;
        sum[ls]=sum[rs]=0;
        cle[ls]=cle[rs]=1;
        tag[ls]=tag[rs]=0;
        cle[rt]=0;
    }
    void Wupd(int rt,int l,int r,int k)
    {
        if(k>0)
        {
            num[rt]+=numb[r]-numb[l-1];
            sum[rt]+=sumcos[r]-sumcos[l-1];
            tag[rt]++;
        }
        else
        {
            num[rt]=sum[rt]=tag[rt]=0;
            cle[rt]=1;
        }
    }
    ll Wq(int rt,int l,int r,int k)
    {
        if(l==r)
        {
            num[rt]-=k,sum[rt]-=b[l].a*k;
            return b[l].a*k;
        }
        if(cle[rt]) Wclerr(rt);
        if(tag[rt]) Wpushdown(rt,l,r);
        ll res=0;
        if(k<=num[ls])
        {
            res+=Wq(ls,l,mid,k);
            Wpushup(rt);
            return res;
        }
        res+=sum[ls]+Wq(rs,mid+1,r,k-num[ls]);
        Wupd(ls,l,mid,-1);
        Wpushup(rt);
        return res;
    }
    short main()
    {
        freopen("a.in","r",stdin),freopen("a.out","w",stdout);
        n=qr,m=qr;
        fo(i,1,n) c[i]=qr;
        fo(i,1,m) b[i].a=qr,b[i].b=qr,b[i].b=(b[i].b==-1?1e12:b[i].b);
        sort(b+1,b+1+m,cmp);
        fo(i,1,m)
        {
            numb[i]=numb[i-1]+b[i].b;
            sumcos[i]=sumcos[i-1]+1ll*b[i].a*b[i].b;
            if(b[i].b==1e12){m=i;break;}
        }
        fo(i,1,n) Wupd(1,1,m,1),ans+=Wq(1,1,m,c[i]);
        printf("%lld\n",ans);
        return Ratio;
    }
}
int main(){return Wisadel::main();}

B. 小W与制胡串谜题

签,但想复杂了所以没签上。

一个排序就解决了,不过看到第二个样例发现直接比较不太行,像 bcabc,于是我就想到了如果存在前缀关系,判断长串后缀与短串的大小,然后由于不清楚 cmp 的比较关系返回值导致搞错了只有 55pts。实际上比较 \(a+b\lt b+a\) 就行了。

点击查看代码
#include<bits/stdc++.h>
#define fo(x,y,z) for(register int (x)((y));(x)<=(z);(x)++)
#define fu(x,y,z) for(register int (x)((y));(x)>=(z);(x)--)
using namespace std;
typedef long long ll;
#define lx int
inline lx qr()
{
	char ch=getchar();lx x=0,f=1;
	for(;ch<'0'||ch>'9';ch=getchar()) if(ch=='-') f=-1;
	for(;ch>='0'&&ch<='9';ch=getchar()) x=(x<<3)+(x<<1)+(ch^48);
	return x*f;
}
#undef lx
#define qr qr()
const int Ratio=0;
const int N=5e5+5;
const int mod=1e9+9;
int n;
string s[N];
bool cmp(string s1,string s2){return string(s1+s2)<string(s2+s1);}
namespace Wisadel
{
    short main()
    {
        freopen("a.in","r",stdin),freopen("a.out","w",stdout);
        n=qr;
        fo(i,1,n) cin>>s[i];
        sort(s+1,s+1+n,cmp);
        fo(i,1,n) cout<<s[i];
        return Ratio;
    }
}
int main(){return Wisadel::main();}

C. 小W与屠龙游戏

由于之前学过博弈论所以看出来了是 Nim Game 的变种,因为当时不会线性基就没看 Nim-k 的实现,后面补上。

突然的考试,有点慌其实。

此 W 非彼 W,差评

打到 1.5h 左右觉得 200pts 是大众分,于是开始被 T3 折磨,想到结束也没想出点啥,感觉学东西学一半就很难受。

看来大家都挂了不少分,致敬大黄首次不挂分反向挂分模拟赛!


完结撒花~

posted @ 2024-09-16 11:07  DrRatio  阅读(21)  评论(2编辑  收藏  举报