zoukankan      html  css  js  c++  java
  • 图论+倍增——cf

    两种思路

    找环模拟: 

    /*
    每个格子都有看成是带一条出边的点(正反图各建一个)
    那么形成的图像很多不相交的环,环上带着链
    所以可以把环单独拉出来算,每个独立的环+链最多放的数量就是环的size
    然后再考虑黑色格子最多
        对于每个独立的环+链,给每个结点编号,定一个环上点为0,其后继是1,前驱是size-1
        用这种方式把整个环+链染好色,然后[0,size-1]没种颜色的点只能有一个 
    */

    倍增:https://www.cnblogs.com/suxxsfe/p/12699630.html

    #include<bits/stdc++.h>
    using namespace std;
    #define N 2000006
    
    int n,m,nxt[N][21],cnt[N],f[N];
    char mp[N],d[N],tmp[N]; 
    
    int id(int i,int j){
        return (i-1)*m+j; 
    }
    void init(){
        for(int i=1;i<=n*m;i++)f[i]=cnt[i]=0;
    }
    
    int main(){
        int t;cin>>t;
        while(t--){
            scanf("%d%d",&n,&m);
            for(int i=1;i<=n;i++){
                scanf("%s",tmp+1);
                for(int j=1;j<=m;j++)
                    mp[id(i,j)]=tmp[j];
            }
            for(int i=1;i<=n;i++){
                scanf("%s",tmp+1);
                for(int j=1;j<=m;j++)
                    d[id(i,j)]=tmp[j];
            }
            init();
            for(int i=1;i<=n;i++)
                for(int j=1;j<=m;j++){                
                    int u,v;
                    if(d[id(i,j)]=='L'){
                        u=id(i,j),v=id(i,j-1);
                    }else if(d[id(i,j)]=='R'){
                        u=id(i,j),v=id(i,j+1);                
                    }else if(d[id(i,j)]=='U'){
                        u=id(i,j),v=id(i-1,j);
                    }else if(d[id(i,j)]=='D'){
                        u=id(i,j),v=id(i+1,j);
                    }
                    nxt[u][0]=v;
                }
            int k=0;
            while((1<<(k+1))<n*m)
                k++;
            for(int i=1;i<=k;i++){
                for(int j=1;j<=n*m;j++)
                    nxt[j][i]=nxt[nxt[j][i-1]][i-1];
            }
            
            //for(int i=1;i<=n*m;i++)cout<<nxt[i][0]<<" ";
            
            for(int i=1;i<=n*m;i++){
                int now=n*m,u=i;
                for(int j=k;j>=0;j--)if(now>=(1<<j)){
                    now-=(1<<j);
                    u=nxt[u][j];
                }
                f[u]++;
                if(mp[i]=='0')cnt[u]++;
            }
            
            int sum1=0,sum2=0;
            for(int i=1;i<=n*m;i++){
                if(f[i])sum1++;
                if(cnt[i])sum2++;
            }
            cout<<sum1<<" "<<sum2<<'
    ';
        }
    } 
  • 相关阅读:
    常见的概念
    cas底层
    判断页面是否读取了缓存
    window.location.hash(hash应用)---跳转到hash值制定的具体页面
    * 输入框被第三方输入法遮挡问题
    Mui去掉滚动条:
    实用网址
    完美解决safari、微信浏览器下拉回弹效果。
    移动端兼容性问题解决方案
    监听ios自带返回功能
  • 原文地址:https://www.cnblogs.com/zsben991126/p/12770739.html
Copyright © 2011-2022 走看看