Submission #374285
Source Code Expand
#ifndef KOMAKI_LOCAL
#define NDEBUG
#endif
#include <bits/stdc++.h>
#include <sys/time.h>
#include <unistd.h>
using namespace std;
#define i64 int64_t
#define rep(i, n) for(i64 i = 0; i < ((i64)(n)); ++i)
#define sz(v) ((i64)((v).size()))
#define bit(n) (((i64)1)<<((i64)(n)))
#define all(v) (v).begin(), (v).end()
std::string dbgDelim(int &i){ return (i++ == 0 ? "" : ", "); }
#define dbgEmbrace(exp) { int i = 0; os << "{"; { exp; } os << "}"; return os; }
template <class T> std::ostream& operator<<(std::ostream &os, std::vector<T> v);
template <class T> std::ostream& operator<<(std::ostream &os, std::set<T> v);
template <class T> std::ostream& operator<<(std::ostream &os, std::queue<T> q);
template <class T> std::ostream& operator<<(std::ostream &os, std::priority_queue<T> q);
template <class T, class K> std::ostream& operator<<(std::ostream &os, std::pair<T, K> p);
template <class T, class K> std::ostream& operator<<(std::ostream &os, std::map<T, K> mp);
template <class T, class K> std::ostream& operator<<(std::ostream &os, std::unordered_map<T, K> mp);
template <int INDEX, class TUPLE> void dbgDeploy(std::ostream &os, TUPLE tuple){}
template <int INDEX, class TUPLE, class H, class ...Ts> void dbgDeploy(std::ostream &os, TUPLE t)
{ os << (INDEX == 0 ? "" : ", ") << get<INDEX>(t); dbgDeploy<INDEX + 1, TUPLE, Ts...>(os, t); }
template <class T, class K> void dbgDeploy(std::ostream &os, std::pair<T, K> p, std::string delim)
{ os << "(" << p.first << delim << p.second << ")"; }
template <class ...Ts> std::ostream& operator<<(std::ostream &os, std::tuple<Ts...> t)
{ os << "("; dbgDeploy<0, std::tuple<Ts...>, Ts...>(os, t); os << ")"; return os; }
template <class T, class K> std::ostream& operator<<(std::ostream &os, std::pair<T, K> p)
{ dbgDeploy(os, p, ", "); return os; }
template <class T> std::ostream& operator<<(std::ostream &os, std::vector<T> v)
{ dbgEmbrace( for(T t: v){ os << dbgDelim(i) << t; }); }
template <class T> std::ostream& operator<<(std::ostream &os, std::set<T> s)
{ dbgEmbrace( for(T t: s){ os << dbgDelim(i) << t; }); }
template <class T> std::ostream& operator<<(std::ostream &os, std::queue<T> q)
{ dbgEmbrace( for(; q.size(); q.pop()){ os << dbgDelim(i) << q.front(); }); }
template <class T> std::ostream& operator<<(std::ostream &os, std::priority_queue<T> q)
{ dbgEmbrace( for(; q.size(); q.pop()){ os << dbgDelim(i) << q.top(); }); }
template <class T, class K> std::ostream& operator<<(std::ostream &os, std::map<T, K> mp)
{ dbgEmbrace( for(auto p: mp){ os << dbgDelim(i); dbgDeploy(os, p, "->"); }); }
template <class T, class K> std::ostream& operator<<(std::ostream &os, std::unordered_map<T, K> mp)
{ dbgEmbrace( for(auto p: mp){ os << dbgDelim(i); dbgDeploy(os, p, "->"); }); }
#define DBG_OUT std::cerr
#define DBG_OVERLOAD(_1, _2, _3, _4, _5, _6, macro_name, ...) macro_name
#define DBG_LINE() { char s[99]; sprintf(s, "line:%3d | ", __LINE__); DBG_OUT << s; }
#define DBG_OUTPUT(v) { DBG_OUT << (#v) << "=" << (v); }
#define DBG1(v, ...) { DBG_OUTPUT(v); }
#define DBG2(v, ...) { DBG_OUTPUT(v); DBG_OUT << ", "; DBG1(__VA_ARGS__); }
#define DBG3(v, ...) { DBG_OUTPUT(v); DBG_OUT << ", "; DBG2(__VA_ARGS__); }
#define DBG4(v, ...) { DBG_OUTPUT(v); DBG_OUT << ", "; DBG3(__VA_ARGS__); }
#define DBG5(v, ...) { DBG_OUTPUT(v); DBG_OUT << ", "; DBG4(__VA_ARGS__); }
#define DBG6(v, ...) { DBG_OUTPUT(v); DBG_OUT << ", "; DBG5(__VA_ARGS__); }
#define DEBUG0() { DBG_LINE(); DBG_OUT << std::endl; }
#define DEBUG(...) \
{ \
DBG_LINE(); \
DBG_OVERLOAD(__VA_ARGS__, DBG6, DBG5, DBG4, DBG3, DBG2, DBG1)(__VA_ARGS__); \
DBG_OUT << std::endl; \
}
class MaximumIndependentSet
{
public:
MaximumIndependentSet(int n);
void addEdge(int a, int b);
void recur(int pos, int mask_num, std::vector<int> &mask);
std::vector<int> getMaximumIndependentSet();
private:
int n;
std::vector<std::vector<int>> relatives;
std::vector<std::vector<int>> edges;
int best_mask_num;
std::vector<int> best_mask;
};
inline void MaximumIndependentSet::recur(int pos, int mask_num, std::vector<int> &mask)
{
if((n - pos) + mask_num <= best_mask_num) return;
if(pos == n){
best_mask_num = mask_num;
best_mask = mask;
return;
}
for(int relative: relatives[pos]){
if(mask[relative]) continue;
bool ok = false;
for(auto adj: edges[relative])if(mask[adj]) ok = true;
if(!ok) return;
}
int not_selected_cnt = 0;
int selected_cnt = 0;
for(int adj: edges[pos]){
if(adj < pos){
if(mask[adj]) selected_cnt += 1;
else not_selected_cnt += 1;
}
}
if(selected_cnt == 0){
mask[pos] = 1;
recur(pos + 1, mask_num + 1, mask);
}
if(not_selected_cnt != edges[pos].size()){
mask[pos] = 0;
recur(pos + 1, mask_num + 0, mask);
}
}
std::vector<int> MaximumIndependentSet::getMaximumIndependentSet()
{
relatives = vector<vector<int>>(n + 1);
for(int pos = 0; pos < n; ++pos){
int maxi = pos;
for(int adj: edges[pos]) maxi = max(maxi, adj);
relatives[maxi + 1].push_back(pos);
}
std::vector<int> mask(n, 0);
best_mask_num = 0;
best_mask = std::vector<int>(n, 0);
recur(0, 0, mask);
vector<int> res;
for(int i = 0; i < n; ++i)if(best_mask[i]) res.push_back(i);
return res;
}
MaximumIndependentSet::MaximumIndependentSet(int n)
{
this->n = n;
edges.resize(n);
}
void MaximumIndependentSet::addEdge(int a, int b)
{
assert(0 <= a && a < n);
assert(0 <= b && b < n);
assert(a != b);
edges[a].push_back(b);
edges[b].push_back(a);
}
/*
tuple<i64, i64> calc(i64 mask, i64 independent_set, vector<int> &independents, vector<tuple<int, int>> &edges_0, vector<tuple<int, int>> &edges_1)
{
const i64 MAX = 50;
int minus_cnt[MAX];
int plus_cnt[MAX];
for(auto t: independents){
minus_cnt[t] = 0;
plus_cnt[t] = 0;
}
i64 cnt = 0;
//DEBUG(mask, independent_set);
for(auto edge: edges_0){
int i_0 = get<0>(edge);
int i_1 = get<1>(edge);
//DEBUG(i_0, i_1);
if(independent_set & bit(i_0)){
if(mask & bit(i_1)) plus_cnt[i_0] += 1;
else minus_cnt[i_0] += 1;
continue;
}else{
if(mask & bit(i_0)) plus_cnt[i_1] += 1;
else minus_cnt[i_1] += 1;
continue;
}
}
for(auto edge: edges_1){
int i_0 = get<0>(edge);
int i_1 = get<1>(edge);
if(((mask & bit(i_0)) == 0) ^ ((mask & bit(i_1)) == 0)) ++cnt;
}
i64 way = 1;
for(auto t: independents){
cnt += max(minus_cnt[t], plus_cnt[t]);
if(minus_cnt[t] == plus_cnt[t]) way *= 2;
}
//DEBUG(cnt, way);
return make_tuple(cnt, way);
}
*/
const i64 MAX = 50;
i64 best_score;
i64 best_way;
i64 cur_score;
i64 n = 0;
vector<i64> global_edges[MAX];
int minus_cnt[MAX];
int plus_cnt[MAX];
int colors[MAX];
void recur(i64 pos, i64 independent_mask, vector<int> &independent_set)
{
if(pos == n){
i64 score = cur_score;
i64 way = 1;
for(auto t: independent_set){
score += max(minus_cnt[t], plus_cnt[t]);
if(minus_cnt[t] == plus_cnt[t]) way *= 2;
}
//DEBUG(pos, independent_mask, independent_set);
//DEBUG(score, way);
if(best_score <= score){
if(best_score < score) best_way = 0;
best_score = score;
best_way += way;
}
return;
}
if(independent_mask & bit(pos)){
recur(pos + 1, independent_mask, independent_set);
}else{
rep(color, 2){
colors[pos] = color;
for(auto adj: global_edges[pos]){
if(independent_mask & bit(adj)){
if(color == 0) minus_cnt[adj] += 1;
else plus_cnt[adj] += 1;
}else if(adj < pos){
if(colors[pos] != colors[adj]) cur_score += 1;
}
}
recur(pos + 1, independent_mask, independent_set);
for(auto adj: global_edges[pos]){
if(independent_mask & bit(adj)){
if(color == 0) minus_cnt[adj] -= 1;
else plus_cnt[adj] -= 1;
}else if(adj < pos){
if(colors[pos] != colors[adj]) cur_score -= 1;
}
}
}
}
}
int main()
{
unordered_map<char, i64> mp;
string s;
cin >> s;
i64 ans = 0;
vector<tuple<i64, i64>> edges;
for(i64 pos = 0; pos < sz(s); pos += 4){
if(mp.count(s[pos + 0]) == 0) mp[s[pos + 0]] = n++;
if(mp.count(s[pos + 2]) == 0) mp[s[pos + 2]] = n++;
if(s[pos + 0] == s[pos + 2]) continue;
edges.push_back(make_tuple(mp[s[pos + 0]], mp[s[pos + 2]]));
}
MaximumIndependentSet obj(n);
for(tuple<i64, i64> tup: edges){
if(get<0>(tup) == get<1>(tup)) continue;
global_edges[get<0>(tup)].push_back(get<1>(tup));
global_edges[get<1>(tup)].push_back(get<0>(tup));
obj.addEdge(get<0>(tup), get<1>(tup));
}
//DEBUG(mp);
//DEBUG(edges);
vector<int> independent_set = obj.getMaximumIndependentSet();
//DEBUG(independent_set);
i64 independent_mask = 0;
for(auto t: independent_set) independent_mask |= bit(t);
/*
i64 not_independent_mask = bit(n) - 1;
set<i64> independent_set_s;
for(auto t: independent_set) independent_set_s.insert(t);
for(auto t: independent_set) not_independent_mask ^= bit(t);
vector<tuple<int, int>> edges_0;
vector<tuple<int, int>> edges_1;
for(auto edge: edges){
int i_0 = get<0>(edge);
int i_1 = get<1>(edge);
//DEBUG(i_0, i_1);
if(((bit(n) - 1) ^ not_independent_mask) & bit(i_0)){
edges_0.push_back(edge);
continue;
}
if(((bit(n) - 1) ^ not_independent_mask) & bit(i_1)){
edges_0.push_back(edge);
continue;
}
edges_1.push_back(edge);
}
*/
/*
i64 best = 0;
i64 way = 0;
for(i64 mask = not_independent_mask; true;){
tuple<i64, i64> tup = calc(mask, (bit(n) - 1) ^ not_independent_mask, independent_set, edges_0, edges_1);
if(best <= get<0>(tup)){
if(best < get<0>(tup)){
best = get<0>(tup);
way = 0;
}
way += get<1>(tup);
}
if(mask == 0) break;
mask = (mask - 1) & not_independent_mask;
}
*/
recur(0, independent_mask, independent_set);
cout << best_way << endl;
}
Submission Info
Submission Time |
|
Task |
L - セミ時雨ハッシュ |
User |
Komaki |
Language |
C++11 (GCC 4.9.2) |
Score |
300 |
Code Size |
10580 Byte |
Status |
AC |
Exec Time |
1206 ms |
Memory |
928 KB |
Judge Result
Set Name |
Subtask |
All |
Score / Max Score |
30 / 30 |
270 / 270 |
Status |
|
|
Set Name |
Test Cases |
Subtask |
subtask_00.txt, subtask_01.txt, subtask_02.txt, subtask_03.txt, subtask_04.txt, subtask_05.txt, subtask_06.txt, subtask_07.txt, subtask_08.txt, subtask_09.txt, subtask_10.txt, subtask_11.txt |
All |
scrambled_00.txt, scrambled_01.txt, scrambled_02.txt, scrambled_03.txt, scrambled_04.txt, scrambled_05.txt, scrambled_06.txt, scrambled_07.txt, scrambled_08.txt, scrambled_09.txt, scrambled_10.txt, scrambled_11.txt, scrambled_12.txt, scrambled_13.txt, scrambled_14.txt, scrambled_15.txt, scrambled_16.txt, scrambled_17.txt, scrambled_18.txt, scrambled_19.txt, scrambled_20.txt, scrambled_21.txt, scrambled_22.txt, scrambled_23.txt, scrambled_24.txt, scrambled_25.txt, scrambled_26.txt, scrambled_27.txt, scrambled_28.txt, scrambled_29.txt, scrambled_30.txt, scrambled_31.txt, scrambled_32.txt, scrambled_33.txt, scrambled_34.txt, scrambled_35.txt, scrambled_36.txt, scrambled_37.txt, subtask_00.txt, subtask_01.txt, subtask_02.txt, subtask_03.txt, subtask_04.txt, subtask_05.txt, subtask_06.txt, subtask_07.txt, subtask_08.txt, subtask_09.txt, subtask_10.txt, subtask_11.txt |
Case Name |
Status |
Exec Time |
Memory |
scrambled_00.txt |
AC |
26 ms |
800 KB |
scrambled_01.txt |
AC |
24 ms |
920 KB |
scrambled_02.txt |
AC |
46 ms |
916 KB |
scrambled_03.txt |
AC |
60 ms |
920 KB |
scrambled_04.txt |
AC |
43 ms |
920 KB |
scrambled_05.txt |
AC |
43 ms |
920 KB |
scrambled_06.txt |
AC |
58 ms |
916 KB |
scrambled_07.txt |
AC |
44 ms |
916 KB |
scrambled_08.txt |
AC |
43 ms |
796 KB |
scrambled_09.txt |
AC |
48 ms |
916 KB |
scrambled_10.txt |
AC |
58 ms |
732 KB |
scrambled_11.txt |
AC |
57 ms |
916 KB |
scrambled_12.txt |
AC |
343 ms |
796 KB |
scrambled_13.txt |
AC |
1206 ms |
928 KB |
scrambled_14.txt |
AC |
57 ms |
920 KB |
scrambled_15.txt |
AC |
57 ms |
916 KB |
scrambled_16.txt |
AC |
60 ms |
792 KB |
scrambled_17.txt |
AC |
53 ms |
920 KB |
scrambled_18.txt |
AC |
53 ms |
840 KB |
scrambled_19.txt |
AC |
53 ms |
924 KB |
scrambled_20.txt |
AC |
55 ms |
792 KB |
scrambled_21.txt |
AC |
24 ms |
920 KB |
scrambled_22.txt |
AC |
25 ms |
924 KB |
scrambled_23.txt |
AC |
25 ms |
916 KB |
scrambled_24.txt |
AC |
24 ms |
920 KB |
scrambled_25.txt |
AC |
25 ms |
920 KB |
scrambled_26.txt |
AC |
25 ms |
920 KB |
scrambled_27.txt |
AC |
25 ms |
920 KB |
scrambled_28.txt |
AC |
25 ms |
916 KB |
scrambled_29.txt |
AC |
25 ms |
920 KB |
scrambled_30.txt |
AC |
25 ms |
920 KB |
scrambled_31.txt |
AC |
26 ms |
732 KB |
scrambled_32.txt |
AC |
30 ms |
916 KB |
scrambled_33.txt |
AC |
29 ms |
920 KB |
scrambled_34.txt |
AC |
28 ms |
800 KB |
scrambled_35.txt |
AC |
61 ms |
924 KB |
scrambled_36.txt |
AC |
36 ms |
920 KB |
scrambled_37.txt |
AC |
31 ms |
732 KB |
subtask_00.txt |
AC |
25 ms |
796 KB |
subtask_01.txt |
AC |
25 ms |
920 KB |
subtask_02.txt |
AC |
25 ms |
788 KB |
subtask_03.txt |
AC |
24 ms |
928 KB |
subtask_04.txt |
AC |
24 ms |
920 KB |
subtask_05.txt |
AC |
24 ms |
920 KB |
subtask_06.txt |
AC |
25 ms |
792 KB |
subtask_07.txt |
AC |
25 ms |
916 KB |
subtask_08.txt |
AC |
25 ms |
920 KB |
subtask_09.txt |
AC |
25 ms |
924 KB |
subtask_10.txt |
AC |
25 ms |
920 KB |
subtask_11.txt |
AC |
25 ms |
916 KB |