2024暑假集訓測試13

卡布叻_周深發表於2024-07-28

前言

  • 比賽連結

image

從來沒見過互動題,T1 狂 CE 不止心態炸了,後面的題也沒打好,T2、T3 簡單題都不會了,所以為啥 T4 又放黑題。

T1 大眾點評

  • 原題:AT_joisc2014_d

難點主要在互動,賽時琢磨了半場比賽終於搞明白是啥玩意兒了,可以將給定庫當成壓縮的一部分程式碼,可以呼叫裡面的函式,輸入輸出已在裡面,因為裡面有主函式了,本地不能再打主函式了。

兩兩配對,大的加入 \(\max\) 集合,小的加入 \(\min\) 集合,再分別掃,共需要 \(n+\dfrac{n}{2}\) 次。

點選檢視程式碼
#include "ramen.h"
#include<bits/stdc++.h>
#define ll long long 
#define endl '\n'
#define sort stable_sort
using namespace std;
const int N=1e5+10;
template<typename Tp> inline void read(Tp&x)
{
    x=0;register bool z=true;
    register char c=getchar();
    for(;c<'0'||c>'9';c=getchar()) if(c=='-') z=0;
    for(;'0'<=c&&c<='9';c=getchar()) x=(x<<1)+(x<<3)+(c^48);
    x=(z?x:~x+1);
}
template<typename Tp> inline void wt(Tp x)
{if(x>9)wt(x/10);putchar((x%10)+'0');}
template<typename Tp> inline void write(Tp x)
{if(x<0)putchar('-'),x=~x+1;wt(x);}
void Ramen(int N)
{
    if(N==1) {Answer(0,0); return ;}
    vector<int>mx,mi;
    int maxx=0,minn=0;
    for(int i=1;i<=N-1;i+=2)
    {
        if(Compare(i-1,i)==1)
        {
            mx.push_back(i-1);
            mi.push_back(i);
            maxx=i-1,minn=i;
        }
        else 
        {
            mx.push_back(i);
            mi.push_back(i-1);
            maxx=i,minn=i-1;
        }
    }
    for(int i:mx) if(i!=maxx) if(Compare(i,maxx)==1) maxx=i;
    for(int i:mi) if(i!=minn) if(Compare(i,minn)==-1) minn=i;
    if(!((N-1)&1)) 
    {
        if(Compare(N-1,maxx)==1) maxx=N-1;
        else if(Compare(N-1,minn)==-1) minn=N-1;
    }
    Answer(minn,maxx);
}

T2 錄取查詢

  • 原題:[ABC285F] Substring of Sorted String

賽時心態崩了這麼簡單的題都沒想出來。

結論就是需滿足區間單調不下降且 \(s_l+1\sim s_r-1\) 之間的字符集在這個區間出現次數等於全域性出現次數,線段樹維護即可,複雜度 \(O(26n\log_n)\)

點選檢視程式碼
#include<bits/stdc++.h>
#define ll long long 
#define endl '\n'
#define sort stable_sort
#define f t[p]
#define ls p<<1
#define rs p<<1|1
using namespace std;
const int N=1e5+10;
template<typename Tp> inline void read(Tp&x)
{
    x=0;register bool z=true;
    register char c=getchar();
    for(;c<'0'||c>'9';c=getchar()) if(c=='-') z=0;
    for(;'0'<=c&&c<='9';c=getchar()) x=(x<<1)+(x<<3)+(c^48);
    x=(z?x:~x+1);
}
template<typename Tp> inline void wt(Tp x)
{if(x>9)wt(x/10);putchar((x%10)+'0');}
template<typename Tp> inline void write(Tp x)
{if(x<0)putchar('-'),x=~x+1;wt(x);}
int n,m,cnt[N];
char s[N],tt;
struct aa 
{
    int l,r,val[30],pre,suf;
    bool flag;
}t[N<<2];
void pushup(int p)
{
    for(int i=0;i<=25;i++)
        f.val[i]=t[ls].val[i]+t[rs].val[i];
    f.flag=(t[ls].flag&&t[rs].flag&&t[rs].pre>=t[ls].suf);
    f.pre=t[ls].pre;
    f.suf=t[rs].suf;
}
void build(int p,int l,int r)
{
    f.l=l,f.r=r;
    if(l==r)
    {
        f.val[s[l]-'a']++;
        f.pre=f.suf=s[l]-'a';
        f.flag=1;
        return ;
    }
    int mid=(l+r)>>1;
    build(ls,l,mid),build(rs,mid+1,r);
    pushup(p);
}
void change(int p,int x,int d)
{
    if(f.l==f.r)
    {
        f.val[s[x]-'a']+=d;
        f.pre=f.suf=s[x]-'a';
        f.flag=1;
        return ;
    }
    int mid=(f.l+f.r)>>1;
    if(x<=mid) change(ls,x,d);
    else change(rs,x,d);
    pushup(p);
}
aa ask(int p,int l,int r)
{
    if(l<=f.l&&r>=f.r) return f;
    int mid=(f.l+f.r)>>1;
    aa ans;
    if(r<=mid) ans=ask(ls,l,r);
    else if(l>mid) ans=ask(rs,l,r);
    else if(l<=mid&&r>mid)
    {
        aa x=ask(ls,l,r),y=ask(rs,l,r);
        for(int i=0;i<=25;i++)
            ans.val[i]=x.val[i]+y.val[i];
        ans.flag=(x.flag&&y.flag&&y.pre>=x.suf);
        ans.pre=x.pre,ans.suf=y.suf;
    }
    return ans;
}
signed main()
{
    read(n); cin>>(s+1);
    for(int i=1;i<=n;i++) cnt[s[i]-'a']++;
    build(1,1,n);
    read(m);
    for(int i=1,op,x,y;i<=m;i++)
    {
        read(op),read(x);
        if(op==1)
        {
            cin>>tt;
            cnt[s[x]-'a']--; change(1,x,-1);
            s[x]=tt;
            cnt[s[x]-'a']++; change(1,x,1);
        }
        else
        {
            read(y);
            aa ans=ask(1,x,y);
            bool flag=ans.flag;
            if(flag) for(int i=s[x]-'a'+1;i<=s[y]-'a'-1;i++)
                if(ans.val[i]!=cnt[i])
                {
                    flag=0;
                    break;
                }
            puts(flag?"Yes":"No");
        }
    }
}

T3 精準打擊

  • [ABC290G] Edge Elimination

是道紫但實際沒那麼難,比較平凡的貪心,因為 \(d\) 很小可以暴力列舉,賽時根本沒時間想。

列舉深度 \(d\),即一棵深度為 \(d\) 的子樹,貪心的角度一定是從大往小拿,將 \(d-1\) 層能拿的都拿了接著向下遞迴即可,最後取最小值。

點選檢視程式碼
#include<bits/stdc++.h>
#define ll long long 
#define endl '\n'
#define sort stable_sort
#define f t[p]
#define ls p<<1
#define rs p<<1|1
using namespace std;
const int N=1e5+10;
template<typename Tp> inline void read(Tp&x)
{
    x=0;register bool z=true;
    register char c=getchar();
    for(;c<'0'||c>'9';c=getchar()) if(c=='-') z=0;
    for(;'0'<=c&&c<='9';c=getchar()) x=(x<<1)+(x<<3)+(c^48);
    x=(z?x:~x+1);
}
template<typename Tp> inline void wt(Tp x)
{if(x>9)wt(x/10);putchar((x%10)+'0');}
template<typename Tp> inline void write(Tp x)
{if(x<0)putchar('-'),x=~x+1;wt(x);}
ll T,d,k,x,a[N];
signed main()
{
    read(T);
    while(T--)
    {
        read(d),read(k),read(x);
        a[0]=1;
        for(int i=1;i<=d;i++) a[i]=a[i-1]*k+1;
        ll ans=1e18;
        for(int i=d;i>=0;i--)
        {
            if(a[i]>=x)
            {
                ll sum=!(i==d);
                for(ll y=a[i]-x,j=i-1;y>0&&j>=0;j--)
                {
                    sum+=y/a[j];
                    y%=a[j];
                }
                ans=min(ans,sum);
            }
            else break;
        }
        write(ans),puts("");
    }
}

T4 你畫我猜

  • 原題:P4459 [BJOI2018] 雙人猜數遊戲

假設 Alice 先說,Alice 說不知道說明 \(n\) 積拆分不唯一,Bob 說不知道說明積拆分不唯一的數中和拆分不唯一,Alice 再說不知道說明積拆分不唯一的數中和拆分不唯一的積拆分不唯一……一次類推,發現是個遞迴。

由此記憶化搜尋即可,直接列舉從小到大列舉 \(n,m\) 判斷其合不合法,不合法指輪數未到 \(t\) 就知道了,每次排除集合內部分元素。

本來就比較抽象的一道題,賽時想出來估計我也調不出來程式碼,手摸又出不來太多組,況且當時心態崩了。

點選檢視程式碼
#include<bits/stdc++.h>
#define ll long long 
#define endl '\n'
#define sort stable_sort
#define pii pair<int,int>
#define fir first
#define sec second
using namespace std;
const int N=1e5+10;
template<typename Tp> inline void read(Tp&x)
{
    x=0;register bool z=true;
    register char c=getchar();
    for(;c<'0'||c>'9';c=getchar()) if(c=='-') z=0;
    for(;'0'<=c&&c<='9';c=getchar()) x=(x<<1)+(x<<3)+(c^48);
    x=(z?x:~x+1);
}
template<typename Tp> inline void wt(Tp x)
{if(x>9)wt(x/10);putchar((x%10)+'0');}
template<typename Tp> inline void write(Tp x)
{if(x<0)putchar('-'),x=~x+1;wt(x);}
int id,lim,need;
string name;
unordered_map<int,int>mp_a,mp_b,ma[20],mb[20];
vector<pii>get_a(int x)
{
    vector<pii>res;
    for(int i=lim;i*i<=x;i++)
        if(x%i==0) res.push_back(make_pair(i,x/i));
    return res;
}
vector<pii>get_b(int x)
{
    vector<pii>res;
    for(int i=lim;i+i<=x;i++)
        res.push_back(make_pair(i,x-i));
    return res;
}
int sum_a(int x)
{
    if(mp_a.count(x)) return mp_a[x];
    int res=0; 
    for(int i=lim;x/i>=i;i++) if(x%i==0) res++;
    return mp_a[x]=res;
}
int sum_b(int x)
{
    if(mp_b.count(x)) return mp_b[x];
    int res=0;
    for(int i=lim;x-i>=i;i++) res++;
    return mp_b[x]=res;
}
vector<pii> dfs_b(int,const vector<pii>&);
int find_b(int,int);
int find_a(int dep,int x)
{
    if(dep==0) return sum_a(x);
    if(ma[dep].count(x)) return ma[dep][x];
    vector<pii>a=get_a(x);
    int res=0;
    for(auto x:a) res+=(find_b(dep-1,x.fir+x.sec)>1);
    return ma[dep][x]=res;
}
int find_b(int dep,int x)
{
    if(dep==0) return sum_b(x);
    if(mb[dep].count(x)) return mb[dep][x];
    vector<pii>b=get_b(x);
    int res=0;
    for(auto x:b) res+=(find_a(dep-1,x.fir*x.sec)>1);
    return mb[dep][x]=res;
}
vector<pii> dfs_a(int dep,const vector<pii> &a)
{
    if(dep==0) return a;
    vector<pii>res;
    for(auto x:a)
        if(find_b(dep-1,x.fir+x.sec)>1)
            res.push_back(make_pair(x.fir,x.sec));
    return res;
}
vector<pii> dfs_b(int dep,const vector<pii> &b)
{
    if(dep==0) return b;
    vector<pii>res;
    for(auto x:b)
        if(find_a(dep-1,x.fir*x.sec)>1)
            res.push_back(make_pair(x.fir,x.sec));
    return res;
}
bool solve(int n,int m)
{
    vector<pii>a=get_a(n*m),b=get_b(n+m);
    if(name=="Alice")
    {
        for(int i=1;i<=need;i++)
        {
            if(i&1) 
            {
                a=dfs_a(i-1,a);
                if(a.size()<=1) return 0;
            }
            else
            {
                b=dfs_b(i-1,b);
                if(b.size()<=1) return 0;
            }
        }
        if(!(need&1))
        {
            a=dfs_a(need,a); int res=0;
            for(auto x:b) 
                if(dfs_a(need,get_a(x.fir*x.sec)).size()==1) 
                    ++res;
            if(a.size()==1&&res==1) return 1;
            else return 0;
        }
        else
        {
            b=dfs_b(need,b); int res=0;
            for(auto x:a)
                if(dfs_b(need,get_b(x.fir+x.sec)).size()==1) 
                    ++res;
            if(b.size()==1&&res==1) return 1;
            else return 0;
        }
    }
    else
    {
        for(int i=1;i<=need;i++)
        {
            if(!(i&1)) 
            {
                a=dfs_a(i-1,a);
                if(a.size()<=1) return 0;
            }
            else
            {
                b=dfs_b(i-1,b);
                if(b.size()<=1) return 0;
            }
        }
        if(need&1)
        {
            a=dfs_a(need,a); int res=0;
            for(auto x:b) 
                if(dfs_a(need,get_a(x.fir*x.sec)).size()==1) 
                    ++res;
            if(a.size()==1&&res==1) return 1;
            else return 0;
        }
        else
        {
            b=dfs_b(need,b); int res=0;
            for(auto x:a)
                if(dfs_b(need,get_b(x.fir+x.sec)).size()==1) 
                    ++res;
            if(b.size()==1&&res==1) return 1;
            else return 0;
        }
    }
    return 0;
}
signed main()
{
    read(id),read(lim); cin>>name; read(need);
    for(int i=lim+lim;;i++)
        for(int j=lim;i-j>=j;j++)
            if(solve(j,i-j))
            {
                write(j),putchar(' '),write(i-j);
                return 0;
            }
}

總結

有點難受心態炸了,就純心態問題了,這次和身體沒關係,硬磕互動了,但是不去磕除了能把 T2 切掉 T3 好好想想還能幹什麼呢,互動早晚要學,掛一次印象更深刻嘛,命中註定吧。

心態需要磨鍊但還是有點難受,至少最近幾次沒掛這麼狠過,但後面的甚至賽場上要是還這樣怎麼辦呢。

附錄

雖然打的很唐但是晚上上了體活又看了電影,後來 T4 搶了學長的最優解贏了一桶泡麵,心情好多了。