[家里训练20_02_16]C

地里有水,多少种形态。

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 typedef long long int ll;
  4 const int len=9;
  5 const ll base=1000000000;
  6 int n,m,a[105][105];
  7 int tot,tmp[105*105];
  8 int dx[4]={-1,0,1,0};
  9 int dy[4]={0,1,0,-1};
 10 bool vis[105][105],can[105][105];
 11 struct BN
 12 {
 13     vector<ll>dig;
 14     BN(ll x=0)
 15     {
 16         dig.push_back(x);
 17     }
 18     BN(vector<ll>x)
 19     {
 20         dig=x;
 21     }
 22     inline void addup(vector<ll>&a)
 23     {
 24         int len=a.size();
 25         for(int i=0;i<len;++i)
 26             if(a[i]>=base)
 27             {
 28                 if(i==len-1)
 29                     a.push_back(0),++len;
 30                 a[i+1]+=a[i]/base;
 31                 a[i]-=a[i]/base*base;
 32             }
 33     }
 34     BN operator+(const BN&A)
 35     {
 36         vector<ll>a=dig;
 37         int len=max(dig.size(),A.dig.size());
 38         while(a.size()<len)
 39             a.push_back(0);
 40         for(int i=0;i<A.dig.size();++i)
 41             a[i]+=A.dig[i];
 42         addup(a);
 43         return BN(a);
 44     }
 45     BN operator*(const BN&A)
 46     {
 47         vector<ll>a;
 48         a.resize(dig.size()+A.dig.size()-1);
 49         for(int i=0;i<A.dig.size();++i)
 50         {
 51             ll x=A.dig[i];
 52             for(int j=0;j<dig.size();++j)
 53                 a[i+j]+=A.dig[i]*dig[j];
 54             addup(a);
 55         }
 56         return BN(a);
 57     }
 58     inline int length(ll x)
 59     {
 60         int i=0;
 61         do{x/=10;++i;}while(x);
 62         return i;
 63     }
 64     void out()
 65     {
 66         cout<<dig[dig.size()-1];
 67         for(int i=dig.size()-2;i>=0;--i)
 68         {
 69             int x=len-length(dig[i]);
 70             while(x--)
 71                 cout<<0;
 72             cout<<dig[i];
 73         }
 74         cout<<endl;
 75     }
 76 }ans[105*105];
 77 struct UUU
 78 {
 79     int fa[105*105];
 80     inline void init()
 81     {
 82         for(int i=1;i<=n*n;++i)
 83             fa[i]=i;
 84     }
 85     inline int find(int x)
 86     {
 87         return fa[x]==x?fa[x]:fa[x]=find(fa[x]);
 88     }
 89 }U;
 90 struct pt
 91 {
 92     int x,y;
 93     pt(int a=0,int b=0):x(a),y(b){}
 94 };
 95 pt Q[105*105];
 96 vector<int>wait;
 97 bool color[105*105];
 98 inline int num(int x,int y)
 99 {
100     return (x-1)*n+y;
101 }
102 inline void merge(int x,int y)
103 {
104     if(!can[x][y])
105         return;
106     int L=1,R=0;
107     Q[++R]=pt(x,y);
108     if(!color[U.find(num(x,y))])
109     {
110         wait.push_back(U.find(num(x,y)));
111         color[U.find(num(x,y))]=1;
112     }
113     while(L<=R)
114     {
115         pt u=Q[L++];
116         x=u.x,y=u.y;
117         for(int i=0;i<4;++i)
118         {
119             int nx=x+dx[i],ny=y+dy[i];
120             if(vis[nx][ny]||!can[nx][ny])
121                 continue;
122             if(!color[U.find(num(nx,ny))])
123             {
124                 wait.push_back(U.find(num(nx,ny)));
125                 color[U.find(num(nx,ny))]=1;
126             }
127             Q[++R]=pt(nx,ny);
128             vis[nx][ny]=1;
129         }
130     }
131 }
132 inline void solve(int x,int c)
133 {
134     for(int i=1;i<=n;++i)
135         for(int j=1;j<=n;++j)
136             vis[i][j]=0,color[num(i,j)]=0;
137     for(int i=1;i<=n;++i)
138         for(int j=1;j<=n;++j)
139             if(a[i][j]<x)
140                 can[i][j]=1;
141     for(int i=1;i<=n;++i)
142         for(int j=1;j<=n;++j)
143             if(can[i][j]&&!vis[i][j])
144             {
145                 wait.clear();
146                 merge(i,j);
147                 BN sum(1);
148                 for(int k=0;k<wait.size();++k)
149                 {
150 //                    cout<<wait[k]<<" ";
151                     sum=sum*ans[U.find(wait[k])];
152                     U.fa[U.find(wait[k])]=U.find(num(i,j));
153                 }
154                 sum=sum+BN(c);
155 //                cout<<": ";
156 //                sum.out();
157                 ans[U.find(num(i,j))]=sum;
158             }
159 //    for(int i=1;i<=n;++i,cout<<endl)
160 //        for(int j=1;j<=n;++j)
161 //            cout<<U.find(num(i,j))<<" ";
162 }
163 int main()
164 {
165 //    freopen("stage.in","r",stdin);
166 //    freopen("stage.out","w",stdout);
167     ios::sync_with_stdio(false);
168     cin>>n>>m;
169     U.init();
170     for(int i=1;i<=n;++i)
171         for(int j=1;j<=n;++j)
172             cin>>a[i][j];
173     for(int i=1;i<=n;++i)
174         for(int j=1;j<=n;++j)
175             ans[num(i,j)]=BN(1);
176     for(int i=1;i<=n;++i)
177         for(int j=1;j<=n;++j)
178             tmp[++tot]=a[i][j];
179     tmp[++tot]=m;
180     sort(tmp+1,tmp+tot+1);
181     tot=unique(tmp+1,tmp+tot+1)-tmp-1;
182     for(int i=1;i<=tot;++i)
183         solve(tmp[i],tmp[i]-tmp[i-1]);
184     BN sum(1);
185     wait.clear();
186     memset(vis,0,sizeof(vis));
187     memset(color,0,sizeof(color));
188     for(int i=1;i<=n;++i)
189         for(int j=1;j<=n;++j)
190             can[i][j]=1;
191     merge(1,1);
192     for(int i=0;i<wait.size();++i)
193         sum=sum*ans[U.find(wait[i])];
194     sum.out();
195     return 0;
196 }
View Code
原文地址:https://www.cnblogs.com/GreenDuck/p/12318120.html