ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Codeforces Round #815 (Div. 2) 全解

2022-08-19 12:01:34  阅读:167  来源: 互联网

标签:rt bit val int id ans 全解 Div 815


目录

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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有