QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#405238#7932. AND-OR closureucup-team992WA 19ms11888kbC++204.6kb2024-05-05 14:43:192024-05-05 14:43:20

Judging History

你现在查看的是最新测评结果

  • [2024-05-05 14:43:20]
  • 评测
  • 测评结果:WA
  • 用时:19ms
  • 内存:11888kb
  • [2024-05-05 14:43:19]
  • 提交

answer

#include <bits/stdc++.h>
using namespace std;

#define F first
#define S second
#define ar array
typedef int uci;
#define int long long
#define rep(i, a, b) for(int i = a; i < (b); ++i)
#define all(x) begin(x), end(x)
#define sz(x) (int)(x).size()
#define ll long long
typedef pair<int, int> pii;
typedef vector<int> vi;
vi val, comp, z, cont;
int Time, ncomps;

vector<vi> comps;
template<class G> int dfs(int j, G& g) {
	int low = val[j] = ++Time, x; z.push_back(j);
	for (auto e : g[j]) if (comp[e] < 0)
		low = min(low, val[e] ?: dfs(e,g));

	if (low == val[j]) {
		do {
			x = z.back(); z.pop_back();
			comp[x] = ncomps;
			cont.push_back(x);
		} while (x != j);
		comps.push_back(cont); cont.clear();
		ncomps++;
	}
	return val[j] = low;
}
template<class G> void scc(G& g) {
	int n = sz(g);
	val.assign(n, 0); comp.assign(n, -1);
	Time = ncomps = 0;
	rep(i,0,n) if (comp[i] < 0) dfs(i, g);
}

vector<int> topo;
int high{};
void getneed(int v, vector<vector<bool>> &dag, vector<int> &mask, vector<bool> &vis){
    vis[v] = true;
    for(int i{}; i < high; ++i){
        if(dag[v][i]){
            if(!vis[i])
                getneed(i, dag, mask, vis);
        }
    }
    topo.push_back(v);
}

int sosdp[1<<20];
void solve(){
    ll N; cin >> N;
    vi A(N); rep(i,0,N) cin >> A[i];

    for(int i{}; i < N; ++i){
        int t = A[i];
        int c{};
        while(t){
            c++;
            t >>= 1;
        }
        high = max(high, c);
    }
    vector<vector<bool>> implies(high, vector<bool>(high, true));

    rep(i,0,N) {
    	rep(j,0,high) {
    		rep(k,0,high) {
    			if(A[i]&(1ll << k) && !(A[i]&(1ll<<j))) {
    				implies[k][j] = false;
    			}
    		}
    	}
    }

    vector<vi> adj(high);
    rep(i,0,high) rep(j,0,high) if(implies[i][j]) adj[i].push_back(j);


    scc(adj);

    if(comps.size() == 1){
        cout << 1 << '\n';
        return;
    }
    vector<vector<bool>> dag(comps.size(), vector<bool>(comps.size()));
    vector<int> cnum(high);
    for(int i{}; i < comps.size(); ++i){
        for(int j : comps[i]){
            cnum[j] = i;
        }
    }


    for(auto &t : comps){
        for(int j : t){
            for(int k : adj[j]){
                if(cnum[j] != cnum[k])
                    dag[cnum[j]][cnum[k]] = true;
            }
        }
    }


    int m = comps.size();
    /*
    for(int i{}; i < m; ++i){
        for(int j{}; j < m; ++j)
            cout << dag[i][j];
        cout << '\n';
    }
    */
    
    vector<int> mask(m);
    vector<bool> vis(m);
    for(int i{}; i < m; ++i){
        if(!vis[i]){
            getneed(i, dag, mask, vis);
        }
    }
    reverse(topo.begin(), topo.end());

    for(int i = topo.size()-1; i >= 0; --i){
        mask[topo[i]] |= (1ll<<i);
        for(int j{}; j < high; ++j){
            if(dag[topo[i]][j]){
                mask[topo[i]] |= mask[j];
            }
        }
    }
    /*
    for(int i : topo)
        cout << i << ' ';
    cout << '\n';
    for(int i{}; i < m; ++i)
        cout << mask[i] << ' ';
    cout << '\n';
    */

    int fh = m/2;
    int sh = (m+1)/2;
    int fmask = (1<<fh)-1;
    int smask = ((1<<sh)-1)<<fh;
    // do the last sh
    for(int i{}; i < (1<<sh); ++i){
        bool bad{};
        for(int j{}; j < sh; ++j){
            if(i&(1<<(j))){
                if((i&(mask[topo[j+fh]]>>fh)) != (mask[topo[j+fh]]>>fh)){
                    bad = true;
                    break;
                }
            }
        }
        if(!bad){
            //cout << i << '\n';
            sosdp[i]++;
        }
    }
    

    for(int i = 19; i >= 0; --i){
        for(int j{}; j < (1<<20); ++j){
            if((j&(1<<i)) == 0){
                sosdp[j] += sosdp[j^(1<<i)];
            }
        }
    }

    /*
    for(int i{}; i < 4; ++i)
        cout << sosdp[i] << ' ';
    cout << '\n';
    */

    // do the first 2^fh
    int out{};
    for(int i{}; i < (1<<fh); ++i){
        bool bad{};
        int maskneed{};
        for(int j{}; j < fh; ++j){
            if(i&(1<<(j))){
                if((i&mask[topo[j]]) != (fmask&mask[topo[j]])){
                    bad = true;
                    break;
                }
                maskneed |= mask[topo[j]];
            }
        }
        /*
        cout << i << ' ' << bad << '\n';
        cout << maskneed << '\n';
        cout << ((maskneed&smask)>>fh) << '\n';
        */
        if(!bad){
            out += sosdp[(maskneed&smask)>>fh];
        }
    }
    out--;
    for(int i{}; i < N; ++i){
        if(A[i] == 0){
            out++;
            break;
        }
    }

    cout << out << '\n';

}

uci main(){
    ios_base::sync_with_stdio(0);
    cin.tie(0), cout.tie(0);
    solve();
}

詳細信息

Test #1:

score: 100
Accepted
time: 19ms
memory: 11888kb

input:

4
0 1 3 5

output:

5

result:

ok 1 number(s): "5"

Test #2:

score: 0
Accepted
time: 19ms
memory: 11696kb

input:

5
0 1 2 3 4

output:

8

result:

ok 1 number(s): "8"

Test #3:

score: -100
Wrong Answer
time: 11ms
memory: 11712kb

input:

49
1097363587067 1096810445814 275012137504 1096739142630 1096809921522 1087071335264 829364908576 949625500192 1087142638448 1096200190829 1097292808175 1095750860656 1087144145776 1097346808827 1095734082416 1096755396578 829230678048 1095663303524 1087072842592 1096216444777 949623992864 10962714...

output:

53

result:

wrong answer 1st numbers differ - expected: '52', found: '53'