2019 ICPC 銀川站

I. Base62(高精度進制轉換)

比賽當時雷菊苣和隊長倆人拿着大數板子摸了一百多行(然後在缺少大數板子的情況下雷菊苣一發過了orz)
今天補題隨便摸了個高精度進制轉換的板子交上去就過了還賊短,,
我好菜,佬們好厲害
const int maxn = 1000;
int  t[maxn], A[maxn];
char str1[maxn], str2[maxn];
int n, m;
void solve()
{
    int i, len, k;
    len = strlen(str1);
    for(i=len; i>=0; --i) t[len-1-i] = str1[i] -(str1[i]<58 ? 48: str1[i]<97 ? 55: 61);
    for(k=0; len;) {
        for(i=len; i>=1; --i) {
            t[i-1] +=t[i]%m*n;
            t[i] /= m;
        }
        A[k++] = t[0] % m;
        t[0] /=m;
        while(len>0&&!t[len-1])  len--;
    }
    str2[k] =NULL;
    for(i=0; i<k; i++)
        str2[k-1-i] = A[i]+(A[i]<10 ? 48: A[i]<36 ? 55:61);
} 
int main()
{
    scanf("%d%d%s",&n, &m, str1);
    solve();
    printf("%s\n",str2);
    return 0;
}
🙂

Largest Common Submatrix(單調棧)

求兩個矩陣的最大相同子矩陣,兩個矩陣位置可以不同
重點在兩個矩陣都是全排列,那麼我們可以做到O(1)找到某數字在另外一個矩陣的位置,
存下b數組中每個數字出現的位置,然後就普通最大01子矩陣寫,,,然後掛掉了QAQ,首先是超時,加了快讀果然很快就WA了(WA12,一開始寫錯一組判斷條件還跑過10個樣例。。神了)
菊苣說是因爲沒有判斷合法性,但是我還是沒想通QAQ
只好又去拿單調棧寫QAQ
入棧的是該點爲右邊界時矩陣的高度和矩陣所能到達的左邊界,最後留在棧內沒彈出來的就以m爲右邊界,否則以j-1爲右邊界
再複習一下單調棧,以單調遞增棧爲例,
入棧時,彈出的最後一個結點就是當前結點的左邊界(代表着最後一個大於當前點的值)
對於該結點彈出的那些結點,當前結點的左邊第一個位置就是他們的右邊界(因爲遍歷到 j - 1 的時候他們還沒有被彈出來,到 j 就要被彈出來了( 你說氣不氣 誤))
int n,m;
pii pos[MAXN];
pii q[MAXN];//單調遞增棧
int high[1111][1111];
int a[1111][1111],b[1111][1111];
int main()
{
    rd(n),rd(m);
    rpp(i,n) rpp(j,m) rd(a[i][j]);
    rpp(i,n) rpp(j,m) rd(b[i][j]),pos[b[i][j]]=make_pair(i,j);
    //
    int ans=0;
    rpp(i,n) rpp(j,m) 
    {
        int x=pos[a[i][j]].first,y=pos[a[i][j]].second;
        if(a[i-1][j]==b[x-1][y]) high[i][j]=high[i-1][j]+1;
        else high[i][j]=1; 
        ans=max(ans,high[i][j]);       
    }
    rpp(i,n)
    {
        int t=0;
        rpp(j,m)
        {
            if(j==1) q[++t]=make_pair(high[i][j],1);//隊列中first存該位置的高度,se位置存該位置向左最遠能延伸到哪
            else
            {
                int x=pos[a[i][j]].first,y=pos[a[i][j]].second;
                if(a[i][j-1]!=b[x][y-1])//這時候隊列裏面的元素已經結束了!再往後就斷了,所以全部彈出
                {
                    while(t>0) ans=max(ans,(j-q[t].second)*q[t].first),--t;
                    q[++t]=make_pair(high[i][j],j);
                }
                else
                {
                    int p=j;
                    while(t>0&&q[t].first>high[i][j])
                        ans=max(ans,(j-q[t].second)*q[t].first),p=q[t].second,--t;
                    q[++t]=make_pair(high[i][j],p);
                }
            }
        }
        while(t>0) ans=max(ans,(m-q[t].second+1)*q[t].first),--t;
    }
    cout<<ans<<endl;
    //stop;
    return 0;
}
😳

B. So Easy

哇這個題,,現場寫了好久還WA了好多發,現在寫就感覺,,,嗯???當時我是腦殘嗎,1A,就想清楚計算行列的貢獻值就行了。
int mn[MAXN];//每一行的最小值
int v[1111][1111];
int main()
{
    int n,x,y;cin>>n;
    rep(i,n) mn[i]=1<<30;
    rep(i,n) rep(j,n) 
    {
        cin>>v[i][j],mn[i]=min(mn[i],v[i][j]);
        if(v[i][j]==-1) x=i,y=j;
    }
    int ans=v[(x+1)%n][y]-mn[(x+1)%n];//列的貢獻
    ans+=v[x][(y+1)%n]-v[(x+1)%n][(y+1)%n]+mn[(x+1)%n];//行對他下一列的貢獻就等同於對他的貢獻
    cout<<ans<<endl;
    //stop;
    return 0;
}
😕

 

G. Pot!!(線段樹)


又是一道在現場瘋狂WA的題。。。現在想想感覺好氣。。。明明很好寫,我是腦殘QAQ
一個教訓就是 線段樹 數組開大點 [MAXN<<2]這樣子QAQ,還有就是不關流居然第五個樣例就撲街了,,,提交前記得關流
還有一個教訓就是 看清數據範圍啊啊啊啊,現場想了好久隊友突然一句x大於2小於10點醒夢中人
#define lc root<<1
#define rc root<<1|1
#define ls root<<1,l,mid
#define rs root<<1|1,mid+1,r
struct IN
{
    int t[MAXN<<2],lazy[MAXN<<2];
    void build(int root,int l,int r)
    {
        if(l==r) {t[root]=0;return;}
        lazy[root]=0;
        int mid=(l+r)>>1;
        build(ls);build(rs);
        t[root]=0;
    }
    void push_down(int root)
    {
        t[lc]+=lazy[root],t[rc]+=lazy[root];
        lazy[lc]+=lazy[root],lazy[rc]+=lazy[root];
        lazy[root]=0;
    }
    void update(int root,int l,int r,int ql,int qr,int v)
    {
        if(ql<=l&&qr>=r)
        {
            t[root]+=v,lazy[root]+=v;
            return ;
        }
        int mid=(l+r)>>1;
        if(lazy[root]) push_down(root);
        if(ql<=mid) update(ls,ql,qr,v);
        if(qr>mid) update(rs,ql,qr,v);
        t[root]=max(t[lc],t[rc]);
    }
    int query(int root,int l,int r,int ql,int qr)
    {
        if(ql<=l&&qr>=r) return t[root];
        int mid=(l+r)>>1;
        if(lazy[root]) push_down(root);
        int ans=0;
        if(ql<=mid) ans=max(ans,query(ls,ql,qr));
        if(qr>mid) ans=max(ans,query(rs,ql,qr));
        return ans;
    }
}t2,t3,t5,t7;
int main()
{
    fast;
    int n,q;cin>>n>>q;
    t2.build(1,1,n);t3.build(1,1,n);t5.build(1,1,n);t7.build(1,1,n);
    while(q--)
    {
        string s;int l,r;
        cin>>s>>l>>r;
        if(s[1]=='U')
        {
            int v;cin>>v;
            if(v==2) t2.update(1,1,n,l,r,1);
            else if(v==3) t3.update(1,1,n,l,r,1);
            else if(v==4) t2.update(1,1,n,l,r,2);
            else if(v==5) t5.update(1,1,n,l,r,1);
            else if(v==6) t2.update(1,1,n,l,r,1),t3.update(1,1,n,l,r,1);
            else if(v==7) t7.update(1,1,n,l,r,1);
            else if(v==8) t2.update(1,1,n,l,r,3);
            else if(v==9) t3.update(1,1,n,l,r,2);
            else if(v==10) t2.update(1,1,n,l,r,1),t5.update(1,1,n,l,r,1);
        }
        else
        {
            int ans=0;
            ans=max(ans,t2.query(1,1,n,l,r));
            ans=max(ans,t3.query(1,1,n,l,r));
            ans=max(ans,t5.query(1,1,n,l,r));
            ans=max(ans,t7.query(1,1,n,l,r));
            cout<<"ANSWER "<<ans<<endl;
        }
    }
    //stop;
    return 0;
}
😶

還有一道沒輸輸入的真·簽到題就不補了,over



(我感覺我也over了QAQ菜的真實)







發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章