zoukankan      html  css  js  c++  java
  • csp-s模拟测试77/78部分题解

     

    Day1T2

    题解

    集合求交,求并维护时间戳,整体+,-维护一个变量

    其实都挺套路的,但我考场什么都没想到,竟然还有60

    代码

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define A 3444444
    const ll sz=5000000;
    ll a[sz];
    ll *b=a+2500000;
    ll ans,m,opt,mark,n,k,size,T=1;
    int main(){
    //    freopen("ex_jihe3.in","r",stdin);
    //    freopen("zj.out","w",stdout);
        scanf("%lld",&m);
        for(ll i=1;i<=m;i++){
            scanf("%lld",&opt);
            if(opt==1){
                scanf("%lld",&k);
                for(ll i=1;i<=k;i++){
                    scanf("%lld",&n);
                    if(b[n-mark]!=T){
                        b[n-mark]=T;
                        ans+=n-mark;
                        size++;
                    }
                }
            }
            else if(opt==2){
                ++T;ans=0;size=0;
                scanf("%lld",&k);
                for(ll i=1;i<=k;i++){
                    scanf("%lld",&n);
                    if(b[n-mark]==T-1){
                        b[n-mark]=T;                
                        ans+=n-mark;
                        size++;
    //                    printf("n-mark=%lld sz=%lld
    ",n-mark,size);
                    }
                }
            }
            else if(opt==3){
                mark++;
            }
            else if(opt==4){
                mark--;
            }
            printf("%lld
    ",ans+mark*size);
        }
    }
    View Code

    Day1T3

    题解

    部分分有一部分是$C_m^2$提示

    我们其他也可以这么做,找到每一个极大联通空地同时联通相同颜色每一对都会造成贡献

    但是这样会有多个联通的情况

    可能会出现最多会出现两个颜色之间四联通,会算重

    必须容斥

    记录下每个块被那个极大联通空地链接

    f1[x][col]记录被x连接颜色为col的情况

    f2[x][y][col]记录被x,y两个联通块链接颜色为col的情况

    f3[x][y][z][col],f4[w][x][y][z][col]

    奇加偶减,f1,f2,f3,f4用map存一下即可

    相邻单独考虑

    代码

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define A 1111
    struct node{
        ll bl1,bl2,bl3,bl4,col;
        node(){}
        node(const ll &a,const ll &b,const ll &c,const ll &d,const ll &e){
            bl1=a,bl2=b,bl3=c,bl4=d,col=e;
        }
        friend bool operator < (const node &a,const node &b){
            if(a.bl1!=b.bl1) return a.bl1<b.bl1;
            if(a.bl2!=b.bl2) return a.bl2<b.bl2;
            if(a.bl3!=b.bl3) return a.bl3<b.bl3;
            if(a.bl4!=b.bl4) return a.bl4<b.bl4;
            return a.col<b.col;
        }
    };
    map<node,ll> mp;
    ll bl[5][A][A],vis[A][A],col[A][A];
    ll nowx[5]={0,1,-1,0,0};
    ll nowy[5]={0,0,0,1,-1};
    ll n,m,k,tim,ans;
    void dfs(ll x,ll y){
        vis[x][y]=tim;
        if(col[x][y]){
            if(!bl[1][x][y]) bl[1][x][y]=tim;
            else if(!bl[2][x][y]) bl[2][x][y]=tim;
            else if(!bl[3][x][y]) bl[3][x][y]=tim;
            else if(!bl[4][x][y]) bl[4][x][y]=tim;
            return ;
        }
        for(ll i=1;i<=4;i++){
            ll xnow=nowx[i]+x,ynow=nowy[i]+y;
            if(xnow>=1&&xnow<=n&&ynow>=1&&ynow<=m&&vis[xnow][ynow]!=tim){
                dfs(xnow,ynow);
            }
        }
    }
    int main(){
    //    freopen("ex_link4.in","r",stdin);
        ll kk;
        scanf("%lld%lld%lld",&n,&m,&kk);
        for(ll i=1;i<=n;i++)
            for(ll j=1;j<=m;j++)
                scanf("%lld",&col[i][j]);
        for(ll i=1;i<=n;i++)
            for(ll j=1;j<=m;j++){
                if(!vis[i][j]&&col[i][j]==0){
                    tim++;
                    dfs(i,j);
                }
            }
        for(ll i=1;i<=n;i++)
            for(ll j=1;j<=m;j++)
                if(col[i][j]){
                    if(bl[1][i][j]){
                        ans+=mp[node(bl[1][i][j],0,0,0,col[i][j])]++;
                    }
                    if(bl[2][i][j]){
                        ans+=mp[node(bl[2][i][j],0,0,0,col[i][j])]++;
                        ans-=mp[node(bl[1][i][j],bl[2][i][j],0,0,col[i][j])]++;
                    }
                    if(bl[3][i][j]){
                        ans+=mp[node(bl[3][i][j],0,0,0,col[i][j])]++;
                        ans-=mp[node(bl[2][i][j],bl[3][i][j],0,0,col[i][j])]++;
                        ans-=mp[node(bl[1][i][j],bl[3][i][j],0,0,col[i][j])]++;
                        ans+=mp[node(bl[1][i][j],bl[2][i][j],bl[3][i][j],0,col[i][j])]++;
                    }
                    if(bl[4][i][j]){
                        ans+=mp[node(bl[4][i][j],0,0,0,col[i][j])]++;
                        ans-=mp[node(bl[1][i][j],bl[4][i][j],0,0,col[i][j])]++;
                        ans-=mp[node(bl[2][i][j],bl[4][i][j],0,0,col[i][j])]++;
                        ans-=mp[node(bl[3][i][j],bl[4][i][j],0,0,col[i][j])]++;
                        ans+=mp[node(bl[1][i][j],bl[2][i][j],bl[4][i][j],0,col[i][j])]++;
                        ans+=mp[node(bl[1][i][j],bl[3][i][j],bl[4][i][j],0,col[i][j])]++;
                        ans+=mp[node(bl[2][i][j],bl[3][i][j],bl[4][i][j],0,col[i][j])]++;
                        ans-=mp[node(bl[1][i][j],bl[2][i][j],bl[3][i][j],bl[4][i][j],col[i][j])]++;
                    }
    //                printf("%lld bl 4=%lld 3=%lld 2=%lld 1=%lld
    ",ans,bl[4][i][j],bl[3][i][j],bl[2][i][j],bl[1][i][j]);
                }
    //    printf("%lld
    ",ans);
        for(ll i=1;i<=n;i++)
            for(ll j=2;j<=m;j++)
                if(col[i][j-1]&&col[i][j]&&col[i][j]==col[i][j-1]){
                    ll ok=1;
                    for(ll k=1;k<=4;k++)
                        for(ll e=1;e<=4;e++)
                            if(bl[k][i][j]&&bl[e][i][j-1]&&bl[k][i][j]==bl[e][i][j-1])
                                ok=0;
                    ans+=ok;
                }
        for(ll i=2;i<=n;i++)
            for(ll j=1;j<=m;j++)
                if(col[i-1][j]&&col[i][j]&&col[i][j]==col[i-1][j]){    
                ll    ok=1;
                    for(ll k=1;k<=4;k++)
                        for(ll e=1;e<=4;e++)
                            if(bl[k][i][j]&&bl[e][i-1][j]&&bl[k][i][j]==bl[e][i-1][j])
                                ok=0;
                ans+=ok;
            }
        printf("%lld
    ",ans);
    }
    View Code

    Day2T3

    题解

    假设环上点为黑点,其他点为白点,我们现在要统计的就是max(白点到最近黑点距离)

    假设黑点中深度最小的为B

    开这样几个数组ff[x]表示从x走到父亲后能走到最远距离

    g[x]表示从x向下走到距离最远是多少

    然而可能有最多两个黑点将路径堵塞,所以记录最大值,次大值,次次大值,

    黑点即使将最大值次大值堵上,你可以走次次大值

    然后贡献可以分为两部分

    每个黑点g,最上点ff

    这样复杂度仍然会炸

    考虑优化求每个黑点g

    发现lca路径上除了lca其他点只和一个儿子黑点相邻

    q[x]表示从x走到父亲路径上向下走但不经过x达到最远点

    然后倍增优化一下

    现在贡献变成g[lca],g[x],g[y],q[lca路径上],ff[lca]

    分别维护一下

    代码

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define A 1111111
    ll n,tot=1,tim,m,t;
    ll head[A],ver[A],nxt[A],du[211111],deep[A],qjdis[A],zj[A];
    ll maxcost[A][25],f[A][25];
    ll ans=0;
    pair<ll,ll>g[A][3],dis[A],ff[A],q[A][25];
    pair<ll,ll>tmp;
    void add(ll x,ll y){
        nxt[++tot]=head[x],head[x]=tot,ver[tot]=y;
    }
    ll lca(ll x,ll y){
        pair<ll,ll> pr;ll now=0;
        pr=make_pair(0,0);    
        if(deep[x]>deep[y]) swap(x,y);
        ll lastx=x,lasty=y;
        for(ll i=t;i>=0;i--){
            if(deep[x]==deep[y]) break;
            if(deep[x]<=deep[f[y][i]]) {
                pr=max(pr,q[y][i]);
                y=f[y][i];
            }
        }
        if(x==y) {
            ll lcq=x;
            return max(pr.first,max(ff[lcq].first,g[lasty][0].first));
        }
        for(ll i=t;i>=0;i--){
            if(f[x][i]!=f[y][i]) {
                pr=max(pr,q[x][i]);
                pr=max(pr,q[y][i]);
                x=f[x][i],y=f[y][i];
            }
        }
        ll lcq=f[x][0];
        if((g[lcq][0].second==x&&g[lcq][1].second==y)||(g[lcq][1].second==x&&g[lcq][0].second==y)){
            now=max(g[lcq][2].first,pr.first);
        }
        else if((g[lcq][0].second==x&&g[lcq][1].second!=y)||(g[lcq][0].second==y&&g[lcq][1].second!=x)){
            now=max(g[lcq][1].first,pr.first);
        }
        else {
            now=max(g[lcq][0].first,pr.first);
        }
        now=max(now,ff[lcq].first);
        now=max(now,max(g[lastx][0].first,g[lasty][0].first));
        return now;
    }
    pair<ll,ll> dfs1(ll x,ll pre){
        dis[x]=make_pair(0,0);
        for(ll i=head[x];i;i=nxt[i]){
            ll y=ver[i];
            if(y==pre) continue ;
            f[y][0]=x;
            deep[y]=deep[x]+1;
            pair<ll,ll> d=dfs1(y,x);
            dis[x]=max(dis[x],d);
        }
        return make_pair(dis[x].first+1,dis[x].second);
    }
    void dfs2(ll x,ll pre){
        pair<ll,ll> fir,sec,thi,tmp;
        for(ll i=head[x];i;i=nxt[i]){
            ll y=ver[i];
            if(y==pre) continue ;
            if((dis[y].first+1)>fir.first){
                thi=sec;sec=fir;fir=make_pair(dis[y].first+1,y);
            }
            else if((dis[y].first+1)>sec.first){
                thi=sec;
                sec=make_pair(dis[y].first+1,y);
            }
            else if((dis[y].first+1)>thi.first){
                thi=make_pair(dis[y].first+1,y);
            }
        }
        g[x][0]=make_pair(fir.first,fir.second);
        g[x][1]=make_pair(sec.first,sec.second);
        g[x][2]=make_pair(thi.first,thi.second);
        for(ll i=head[x];i;i=nxt[i]){
            ll y=ver[i];
            if(y==pre) continue ;
            if(dis[y].first+1==fir.first) q[y][0]=sec;
            else q[y][0]=fir;
        }
        for(ll i=head[x];i;i=nxt[i]){
            ll y=ver[i];
            if(y==pre) continue ;
            dfs2(y,x);
        }
    }
    void redfs(ll x,ll pre){
        for(ll i=head[x];i;i=nxt[i]){
            ll y=ver[i];
            if(y==pre) continue ;
            ff[y]=ff[x];
            if(y==g[x][0].second)
                ff[y]=max(ff[y],g[x][1]);
            else ff[y]=max(ff[y],g[x][0]);
            ff[y]=make_pair(ff[y].first+1,ff[y].second);
        }
        for(ll i=head[x];i;i=nxt[i]){
            ll y=ver[i];
            if(y==pre) continue ;
            redfs(y,x);
        }
    }
    void dfs3(ll x,ll pre){
        for(ll i=head[x];i;i=nxt[i]){
            ll y=ver[i];
            if(y==pre) continue ;
            dfs3(y,x);
            ans=max(zj[x]+zj[y]+1,ans);
            zj[x]=max(zj[x],zj[y]+1);
        }
    }
    int main(){
        scanf("%lld",&n);
        t=log(n)/log(2)+1;
        for(ll i=1;i<n;i++){
            ll a,b;
            scanf("%lld%lld",&a,&b);
            add(a,b);
            add(b,a);
        }
        dfs1(1,0);
        dfs2(1,0);
        dfs3(1,0);
        redfs(1,0);
        f[1][0]=1;
        for(ll j=1;j<=t;j++){
            for(ll i=1;i<=n;i++){
                f[i][j]=f[f[i][j-1]][j-1];
                q[i][j]=max(q[f[i][j-1]][j-1],q[i][j-1]);
            }
        }
        scanf("%lld",&m);
        for(ll i=1;i<=m;i++){
            ll a,b;
            scanf("%lld%lld",&a,&b);
            if(a==b){
                printf("%lld
    ",(ans)/2+1);
                continue ;
            }
            printf("%lld
    ",lca(a,b));
        }
    }
    View Code
  • 相关阅读:
    linux 下安装web开发环境
    Nginx服务器之 Nginx的基本配置
    Nginx服务器之基础学习
    java反射 之 反射基础
    java IO流 之 其他流
    java IO流 之 字符流
    java IO流 之 字节流
    java 线程 Lock 锁使用Condition实现线程的等待(await)与通知(signal)
    java线程 公平锁 ReentrantLock(boolean fair)
    MarkdownPad 2破解
  • 原文地址:https://www.cnblogs.com/znsbc-13/p/11717557.html
Copyright © 2011-2022 走看看