codeforces 794 (#414 DIV1+DIV2)

A Bank Robbery[1/1]
B Cutting Carrot[1/1]
C Naming Company[1/3]

博弈····其实挺有趣,得想到如果我的最小的要比他的最大的要优就放在前面否则就放在后面

#include <bits/stdc++.h>
using namespace std;
char a[300010],b[300010];
int ans[300010];
int main(int argc, char const *argv[])
{
    scanf("%s%s",a+1,b+1);
    int n=strlen(a+1);
    sort(a+1,a+1+n);sort(b+1,b+1+n,greater<char>());
    int l=1,r=n,al=1,ar=(n+1)/2,bl=1,br=n/2;
    while(l<=r)
    {
        if(a[al]<b[bl])ans[l++]=a[al++];
        else ans[r--]=a[ar--];if(l>r)break;
        if(a[al]<b[bl])ans[l++]=b[bl++];
        else ans[r--]=b[br--];
    }
    for(int i=1;i<=n;i++)printf("%c",ans[i]);
}
D Labelling Cities[0/1]

还没A,待补

E Choosing Carrot[1/2]

博弈结论,推导很有意思,虽然一开始有一点这样的想法···但是并没有想出来··qwq我没有智商···看了题解才会写···记录一下写法拓展一下思路····

划归一下博弈,假设剩下某个特定数字为赢剩下都为输这样看来最后的结果一定会是

$if (n为偶数 ) ans = max(a_{\frac{n}{2}},a_{\frac{n+1}{2}}) $

\(else\quad ans = min(a_{\frac{n+1}{2}},max(a_{\frac{n-1}{2}},a_{\frac{n+3}{2}}))\)

#include <bits/stdc++.h>
using namespace std;
int ans[3000010];
int l[3000010][2],a[3000010];
int mx=0;
int main(int argc, char const *argv[])
{
    int n;scanf("%d",&n);
    for(int i=1;i<=n;i++)scanf("%d",&a[i]),mx=max(mx,a[i]);
    if(n == 1){printf("%d\n",a[1] );return 0;}
    for(int i=1;i<n;i++)
        l[i][0]=max(a[i],a[i+1]),
        l[i][1] = min(a[i+1],max(a[i],a[i+2]));
        l[n][1]=a[n];
        l[0][1]=a[1];
    for(int i=0;i<=n;i++)ans[i]=max(l[(n+i)/2][(n-i)%2],l[(n-i)/2][(n-i)%2]);
    printf("%d %d ",ans[0],ans[1] );
    for(int i=2;i<n-1;i++)
        ans[i]=max(ans[i],ans[i-2]),printf("%d ",ans[i]);
    printf("%d\n",mx );
    return 0;
}
F Leha and security system[1/14]

很有趣的线段树的问题 (你还是不懂线段树)

WA成sb···OAO太菜了qwq····

首先得清楚 \(T[now]. nxt[i]\) 所有的含义与性质···当前区间的 \(i\) 需要转变为 \(T[now]. nxt[i]\)

而向下传的时候需要更新下面的\(T[now<<1].nxt[i]\)(以\(now<<1\) 为例)

比如说 \(now\) 部分为 \(j->k\) 下方为 \(i -> j\) 更新后变成\(i->j->k\) 所以需要\(i->k\)

\(T[now<<1].nxt[i] = T[now].nxt[T[now<<1].nxt[i]]\) (一定要临时存一下QAQ)

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int a[200010];
struct segment
{
    int l,r;
    ll sum[11];
    int nxt[11];
}T[100010<<3];
void pushup(int now)
{
    for(int i=0;i<10;i++)T[now].sum[i]=T[now<<1].sum[i]+T[now<<1|1].sum[i];
}
void build(int now,int l,int r)
{
    T[now].l = l,T[now].r = r;
    for(int i=0;i<=9;i++)T[now].nxt[i] = i;
    if(l == r){
        ll x = a[l],tot = 1ll,s;
        while(x)
        {
            s = x%10;
            T[now].sum[s]+=tot;
            tot*=10;x/=10;
        }
        return;
    }
    int m=(l+r)>>1;
    build(now<<1,l,m);build(now<<1|1,m+1,r);
    pushup(now);
}
int nxt1[11],nxt2[11];
void pushdown(int now)
{
    int l = T[now].l,r = T[now].r;
    if(r - l>=1){
        for(int i=0;i<=9;i++){
            nxt1[i] = T[now].nxt[T[now<<1].nxt[i]];
            nxt2[i] = T[now].nxt[T[now<<1|1].nxt[i]];
        }
        for(int i=0;i<=9;i++)T[now<<1].nxt[i] = nxt1[i];
        for(int i=0;i<=9;i++)T[now<<1|1].nxt[i] = nxt2[i];
    }
    ll tmp[11]={0};
    for(int i=0;i<=9;i++)tmp[T[now].nxt[i]]+=T[now].sum[i];
    for(int i=0;i<=9;i++)T[now].sum[i]=tmp[i],T[now].nxt[i]=i;
}
void modify(int now,int L,int R,int x,int y)
{
    int l = T[now].l,r=T[now].r;
    if(l>=L&&r<=R)
    {
        T[now].nxt[x]=y;pushdown(now);return;
    }
    int m = (l+r)>>1;
    pushdown(now<<1);pushdown(now<<1|1);
    if(L<=m)modify(now<<1,L,R,x,y);
    if(R>m)modify(now<<1|1,L,R,x,y);
    pushup(now);

}
ll query(int now,int L,int R)
{
    int l = T[now].l,r=T[now].r;
    ll sum=0;
    if(l>=L&&r<=R){
        for(int i=0;i<=9;i++)sum+=T[now].sum[i]*i;
        return sum;
    }
    int m = (l+r)>>1;
    pushdown(now<<1);pushdown(now<<1|1);
    if(L<=m)sum+=query(now<<1,L,R);
    if(R>m)sum+=query(now<<1|1,L,R);
    return sum;
}
int main()
{
    int n,q;scanf("%d%d",&n,&q);
    for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    build(1,1,n);
    int l,r,x,y,s;
    while(q--)
    {
        scanf("%d",&s);
        if(s == 1)
        {
            scanf("%d%d%d%d",&l,&r,&x,&y);if(x == y)continue;
            modify(1,l,r,x,y);
        }
        else 
        {
            scanf("%d%d",&l,&r);
            printf("%lld\n", query(1,l,r));
        }
    }
    return 0;
}
G Replace All

待补··

转载于:https://www.cnblogs.com/miamiao/p/8776842.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值