其他分享
首页 > 其他分享> > Codeforces Round #815 (Div. 2) 全解

Codeforces Round #815 (Div. 2) 全解

作者:互联网

目录

A

ad和cb,查看是不是相等或者倍数关系,特判0

B

sort()
cout<<a[n]+a[n-1]-a[1]-a[2]

C

查看所有的四方格
一个四方格有2个0,ans=1的个数
一个四方格有1个0,ans=1的个数-1
一个四方格有0个0,ans=1的个数-2

D1

直接暴力从前260个转移

D2

类似trie树。
i和ai的二进制相等去左儿子,不相等去右儿子

#include <bits/stdc++.h>
#define FOR(i,a,b) for(int i=a;i<=b;++i)
#define ll long long
using namespace std;
const int _=1e7+7;
// const int mod=1e9+7;
int read() {
    int x=0,f=1;char s=getchar();
    for(;s>'9'||s<'0';s=getchar()) if(s=='-') f=-1;
    for(;s>='0'&&s<='9';s=getchar()) x=x*10+s-'0';
    return x*f;
}
int n,m,a[_],f[_];
struct node {
    int val[4];
    int ch[2];
    //ch[0]; 01 10
    //ch[1]; 00 11
}e[_];
int cnt;
void find(int id,int val,int bit,int rt) {
    if(!rt) return;
    if(bit==-1) return;
    int id_=(id>>bit)&1ll;
    int val_=(val>>bit)&1ll;
    if(id_==val_) {
        if(id_==1)
            f[id]=max(f[id],e[rt].val[0]+1);
        else
            f[id]=max(f[id],e[rt].val[1]+1);
        find(id,val,bit-1,e[rt].ch[1]);
    }
    if(id_!=val_) {
        if(id_==1)
            f[id]=max(f[id],e[rt].val[3]+1);
        else
            f[id]=max(f[id],e[rt].val[2]+1);
        find(id,val,bit-1,e[rt].ch[0]);
    }
}
void insert(int id,int val,int bit,int &rt) {
    if(bit==-1) return;
    if(!rt) rt=++cnt;
    int id_=(id>>bit)&1ll;
    int val_=(val>>bit)&1ll;
    if(id_==val_) {
        if(id_==1)
            e[rt].val[3]=max(e[rt].val[3],f[id]);
        else
            e[rt].val[2]=max(e[rt].val[2],f[id]);
        insert(id,val,bit-1,e[rt].ch[1]);
    } else {
        if(id_==1)
            e[rt].val[1]=max(e[rt].val[1],f[id]);
        else
            e[rt].val[0]=max(e[rt].val[0],f[id]);
        insert(id,val,bit-1,e[rt].ch[0]);
    }
}
void solve() {
    for(int i=0;i<=cnt+10;++i) {
        e[i].ch[0]=e[i].ch[1]=0;
        for(int j=0;j<4;++j) e[i].val[j]=0;
    }
    cnt=0;
    n=read();
    for(int i=0;i<n;++i) a[i]=read(),f[i]=0;
    int ans=0,rt=0;
    for(int i=0;i<n;++i) {
        f[i]=1;
        find(i,a[i],30,rt);
        insert(i,a[i],30,rt);
        ans=max(ans,f[i]);
    }
    cout<<ans<<"\n";
}
signed main() {
    #ifdef ONLINE_JUDGE
    #else
        freopen("a.in","r",stdin);
        // freopen("a.out","w",stdout);
    #endif
    int T=read();
    while(T--) {
        solve();
    }   
    return 0;
}

E

不同的数字很少答案就是k-cnt,不然答案只可能小于等于2
0的情况很好判断。
1的情况就是枚举每个点,然后每一层的拓展是单调的,可以省去一个复杂度,最后是O(n^3)
其他的情况就是2

#include <bits/stdc++.h>
#define FOR(i,a,b) for(int i=a;i<=b;++i)
#define ll long long
using namespace std;
const int _=1e6+7;
// const int mod=1e9+7;
int read() {
    int x=0,f=1;char s=getchar();
    for(;s>'9'||s<'0';s=getchar()) if(s=='-') f=-1;
    for(;s>='0'&&s<='9';s=getchar()) x=x*10+s-'0';
    return x*f;
}
int n,m,limit[_],a[600][600],cnt[_];
int main() {
    #ifdef ONLINE_JUDGE
    #else
        freopen("a.in","r",stdin);
        // freopen("a.out","w",stdout);
    #endif
    n=read(),m=read();
    int tot=0;
    FOR(i,1,n) FOR(j,1,n) a[i][j]=read(),limit[a[i][j]]++;
    FOR(i,1,n*n) tot+=(bool)limit[i];
    if(tot<=m) {
        cout<<m-tot<<'\n';
        return 0;
    }
    FOR(i,1,n) {
        FOR(j,0,n*n) cnt[j]=0;
        int r=0,ans=tot;
        FOR(j,1,n) {
            while(i+r<=n&&j+r<=n&&ans>m) {
                FOR(k,0,r) {
                    auto x=a[i+r][j+k],y=a[i+k][j+r];
                    if(++cnt[x]==limit[x]) ans--;
                    if(k==r) continue;
                    if(++cnt[y]==limit[y]) ans--;
                } r++;
            }
            if(ans>m) break;
            if(ans==m-1||ans==m) {
                cout<<"1\n";
                return 0;
            }
            if(ans<m) {
                r--;
                FOR(k,0,r) {
                    auto x=a[i+r][j+k],y=a[i+k][j+r];
                    if(cnt[x]--==limit[x]) ans++;
                    if(k==r) continue;
                    if(cnt[y]--==limit[y]) ans++;
                }
            }
            FOR(k,0,r-1) {
                auto x=a[i+k][j],y=a[i+k][j+r];
                if(cnt[x]--==limit[x]) ans++;
                if(++cnt[y]==limit[y]) ans--;
            }
        }
    }
    cout<<2<<"\n";
    return 0;
}
/*
3 2
2 1 3
2 1 1
3 1 2
*/

标签:rt,bit,val,int,id,ans,全解,Div,815
来源: https://www.cnblogs.com/acmnb/p/16601525.html