题目链接
第一行和第二行直接暴力枚举,然后维护三个数(以下三个数都为去掉第一行和第二行选过的数),第三行和第四行都有的数的个数two,和第三行自己拥有的数tone,第四行自己拥有的数fone。
那么第三行有两种情况,如果选到了tone,第四行随便选,贡献是
如果选到了two,第四行选择就少了一个,即
时间复杂度
#include <bits/stdc++.h> using namespace std; #define BUFF ios::sync_with_stdio(false), cin.tie(0), cout.tie(0) #define DEBUG(var) cout << #var << "=" << var << '\n' #define REP(i, a, n) for (int i = a; i <= n; ++i) #define PER(i, n, a) for (int i = n; i >= a; --i) #define LL int64_t template<typename T>void Read(T &x){x=0;char ch=getchar();LL f=1;while(!isdigit(ch)){if(ch=='-')f*=-1;ch=getchar();}while(isdigit(ch)){x=x*10+ch-48;ch=getchar();}x*=f;} template<typename T,typename... Args>void Read(T &x,Args&... args){Read(x);Read(args...);} template<typename T>int64_t __lcm(T a, T b){return a/__gcd(a,b)*b;} mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count()); inline int64_t Rand(LL a,LL b) {return a + rng() % (b-a+1);} inline int64_t QuickPow(LL base,LL n,LL Mod=0){LL ret(1);while(n){if(n&1){ret*=base;if(Mod)ret%=Mod;}base*=base;if(Mod)base%=Mod;n>>=1;}return Mod?ret%Mod:ret;} inline int64_t Inv(LL x,LL p){return QuickPow(x,p-2,p);} inline void gettime(){time_t rawtime;struct tm *ptminfo;time(&rawtime);ptminfo = localtime(&rawtime);printf("Current time: %02d-%02d-%02d %02d:%02d:%02d\n",ptminfo->tm_year + 1900, ptminfo->tm_mon + 1, ptminfo->tm_mday,ptminfo->tm_hour, ptminfo->tm_min, ptminfo->tm_sec);} const double pi = acos(-1.0); const LL kInf(1e18); const LL kMod(998244353); const LL kMax(1e5 + 10); LL group(1),ii(1); char str[5][5010]; vector<int>used; int tone,fone,two; LL res = 0; int n; int mp[10][5050]; void dfs(int deep){ if(deep == 1){ for(int i = 1;i <= n;i++){ if(str[deep][i] == '1'){ used.push_back(i); dfs(deep+1); used.pop_back(); } } } else if(deep == 2){ for(int i = 1;i <= n;i++){ if(i == used.back())continue; if(str[deep][i] == '1'){ used.push_back(i); dfs(deep+1); used.pop_back(); } } } else{ int twof = 0;; int tonef = 0; int fonef = 0; for(auto it:used){ if(mp[3][it] == 1 && mp[4][it] == 1){ two--; twof ++; } else if(mp[3][it] == 1){ tone--; tonef ++; } else if(mp[4][it] == 1){ fone--; fonef ++; } } //cout<<two<<" "<<tone<<" "<<fone<<'\n'; res += tone*(two+fone)+two*(two-1+fone); //cout<<tone*(two+fone)+two*(two-1+fone)<<'\n'; two+=twof; tone += tonef; fone += fonef; } } inline void Solve() { /*write your code down here*/ tone = 0; fone = 0; cin>>n; for(int j = 1;j <= 4;j++){ scanf("%s",str[j]+1); } for(int i = 3;i <= 4;i++){ for(int j = 1;j <= n;j++){ if(str[i][j] == '1'){ mp[i][j]++; } } } //puts("haha"); for(int i = 1;i <= n;i++){ if(mp[3][i] == 1&&mp[4][i] == 1){ two++; } else if(mp[3][i] == 1){ tone++; } else if(mp[4][i] == 1){ fone++; } } //cout<<two<<" "<<tone<<" "<<fone<<'\n'; dfs(1); cout<<res<<'\n'; } int main() { //Read(group); //gettime(); for(;ii <= group;ii++) { Solve(); } return 0; }