Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //in the name of allah
- #include<iostream>
- #include<algorithm>
- #include<queue>
- #include<deque>
- #include<set>
- #include<map>
- #include<bitset>
- #include<cstdio>
- #include<cstdlib>
- #include<cassert>
- #include<string>
- #include<cstring>
- #include<vector>
- using namespace std;
- typedef pair<int , int> ii;
- typedef long long ll;
- const int maxn = 3e5+10 , maxm = 2e6+10 , mod = 1e9+7;
- vector<int> g[maxn] , r[maxn] , cmp[maxn] , tp;
- vector<ii> e;
- int n , m , A , B , st[maxn] , len[maxn] , siz[maxn] , d[maxn] , mx[maxn] , mn[maxn] , fact[maxn] , inv[maxn] , sz;
- string a[maxn] , b[maxn];
- bool vis[maxn];
- inline int mul(int a , ll b){
- return (a * b) % mod;
- }
- inline int add(int a , ll b){
- return (a + b + 2LL*mod) % mod;
- }
- inline int bp(int a , int b){
- if(b == 0)
- return 1;
- int x = bp(a , b/2);
- x = mul(x , x);
- return b&1 ? mul(x,a) : x;
- }
- inline int C(int m , int n){
- return n>=m ? mul(fact[n] , mul(inv[m] , inv[n-m])) : 0;
- }
- void dfs(int v){
- vis[v] = true;
- for(auto u : g[v])
- if(!vis[u])
- dfs(u);
- tp.push_back(v);
- }
- void sfd(int v){
- vis[v] = true;
- st[v] = sz;
- cmp[sz].push_back(v);
- len[sz] = len[sz] == 0 ? siz[v] : __gcd(len[sz] , siz[v]);
- for(auto u : r[v])
- if(!vis[u])
- sfd(u);
- }
- int main(){
- scanf("%d%d%d" , &n , &A , &B);
- char STR[maxn];
- for(int i=0 ; i<n ; i++){
- scanf("%s" , STR);
- for(int j=0 ; j<n ; j++){
- if(STR[j] == '1'){
- g[i].push_back(j);
- r[j].push_back(i);
- e.push_back(ii(i , j));
- }
- }
- }
- char str[maxm];
- for(int i=0 ; i<n ; i++){
- scanf("%d%s" , &siz[i] , str);
- mn[i] = 0;
- for(int j=0 ; j<siz[i] ; j++){
- a[i].push_back(str[j]);
- mn[i] += (str[j] == '1');
- }
- }
- if(A<B){
- puts("0");
- return 0;
- }
- for(int i=0 ; i<n ; i++)
- if(!vis[i])
- dfs(i);
- memset(vis , 0 , sizeof vis);
- while((int)tp.size()){
- int i = tp.back();
- tp.pop_back();
- if(!vis[i]){
- sfd(i);
- sz ++;
- }
- }
- for(int i=0 ; i<sz ; i++){
- for(int j=0 ; j<len[i] ; j++)
- b[i] += "0";
- for(auto j : cmp[i])
- for(int k=0 ; k<(int)a[j].size() ; k++)
- b[i][k%len[i]] = char(a[j][k] | b[i][k%len[i]]);
- }
- for(int i=0 ; i<n ; i++)
- g[i].clear();
- for(auto i : e)
- if(st[i.first] != st[i.second])
- g[st[i.first]].push_back(st[i.second]) , d[st[i.second]] ++;
- int cur = -1;
- for(int i=0 ; i<sz ; i++)
- if(d[i] == 0)
- cur = i;
- while(cur != -1){
- int v = cur;
- cur = -1;
- int ptr=0;
- for(auto u : g[v]){
- d[u] --;
- if(d[u] == 0)
- cur = u;
- }
- if(cur == -1)
- break;
- int u = cur;
- int g = __gcd(len[v] , len[u]);
- string str;
- for(int i=0 ; i<g ; i++)
- str += "0";
- for(int i=0 ; i<b[v].size() ; i++)
- str[i%g] = char(b[v][i] | str[i%g]);
- for(int i=0 ; i<b[u].size() ; i++)
- b[u][i] = char(b[u][i] | str[i%g]);
- }
- for(int i=0 ; i<sz ; i++){
- int score=0;
- for(int j=0 ; j<b[i].size() ; j++)
- score += (b[i][j] == '1');
- for(auto j : cmp[i])
- mx[j] = score*(siz[j]/len[i]);
- }
- fact[0] = inv[0] = 1;
- for(int i=1 ; i<=n ; i++){
- fact[i] = mul(i , fact[i-1]);
- inv[i] = bp(fact[i] , mod-2);
- }
- vector<ii > v;
- for(int i=0 ; i<n ; i++){
- v.push_back(ii(mn[i] , 0));
- v.push_back(ii(mx[i] , 1));
- }
- sort(v.begin() , v.end());
- int numa=0 , numb=0 , ans=0;
- for(int i=2*n-1 ; i>=0 ; i--){
- numa += (v[i].second == 0);
- numb += v[i].second;
- if(v[i].second && numb >= B){
- for(int j=0 ; j<=B-1 && j<=numa ; j++){
- int cnt = numa-j;
- if(cnt>A-B)
- continue;
- ans = add(ans , mul(C(j , numa) , C(B-j-1 , numb-1-numa)));
- }
- }
- }
- printf("%d\n" , ans);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement