#define _CRT_SECURE_NO_WARNINGS #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #undef max #undef min #ifdef __GNUC__ #pragma GCC diagnostic ignored "-Wunused-result" #endif #ifdef _DEBUG #define ASSERT(x) if(!(x)) __debugbreak() #else char *crash_please = (char *)42; #define ASSERT(x) //if(!(x)) { printf("%s failed",#x); *crash_please=33; } #endif #include class cLogPerformance_Guard { std::chrono::time_point mStartTime = std::chrono::high_resolution_clock::now(); const char *mName; public: cLogPerformance_Guard(const char *Name): mName(Name) {} ~cLogPerformance_Guard() { auto EndTime = std::chrono::high_resolution_clock::now(); auto Elapsed = std::chrono::duration_cast(EndTime - mStartTime); // printf("--- Elapsed %llu ms in %s ---\n", (unsigned long long)Elapsed.count(), mName); } }; using namespace std; using namespace std::string_literals; using ull = unsigned long long; using ll = long long; //constexpr ll mod=1'000'000'007; constexpr ll mod = 1'000'000'000; template auto rev(I i) { return std::reverse_iterator(i); } #define RI(var_name) int var_name; scanf("%d", &var_name); #define RIV(var_name, size) vector var_name(size); for(auto &item_of_##var_name: var_name) scanf("%d", &item_of_##var_name); #define RII(var_name1, var_name2) int var_name1, var_name2; scanf("%d %d", &var_name1, &var_name2); #define RIII(var_name1, var_name2, var_name3) int var_name1, var_name2, var_name3; scanf("%d %d %d", &var_name1, &var_name2, &var_name3); #define RIIII(var_name1, var_name2, var_name3, var_name4) int var_name1, var_name2, var_name3, var_name4; scanf("%d %d %d %d", &var_name1, &var_name2, &var_name3, &var_name4); #define RL(var_name) ll var_name; scanf("%lld", &var_name); #define RLV(var_name, size) vector var_name(size); for(auto &item_of_##var_name: var_name) scanf("%lld", &item_of_##var_name); #define RLL(var_name1, var_name2) ll var_name1, var_name2; scanf("%lld %lld", &var_name1, &var_name2); #define RLLL(var_name1, var_name2, var_name3) ll var_name1, var_name2, var_name3; scanf("%lld %lld %lld", &var_name1, &var_name2, &var_name3); #define RLLLL(var_name1, var_name2, var_name3, var_name4) ll var_name1, var_name2, var_name3, var_name4; scanf("%lld %lld %lld %lld", &var_name1, &var_name2, &var_name3, &var_name4); #define RD(var_name) double var_name; scanf("%lf", &var_name); #define RDV(var_name, size) vector var_name(size); for(auto &item_of_##var_name: var_name) scanf("%d", &item_of_##var_name); #define RDD(var_name1, var_name2) double var_name1, var_name2; scanf("%lf %lf", &var_name1, &var_name2); #define RDDD(var_name1, var_name2, var_name3) double var_name1, var_name2, var_name3; scanf("%lf %lf %lf", &var_name1, &var_name2, &var_name3); #define ALL(cont) cont.begin(), cont.end() #define FOR(var, max_value) for(int var=0;var>1; x|=x>>2; x|=x>>4; x|=x>>8; x|=x>>16; x|=x>>32; return x&~(x>>1); } ull ones_up_till_highest_bit(ull x) // for example 0000'0000'0010'1101 --> 0000'0000'0011'1111 { return x==0?0:(((isolate_highest_bit(x)-1ull)<<1ull)|1ull); } struct cSegmentData { int lazy_add=0; int max_value=0; ///////////////////////////// ll first_index, length=1; }; class cSegmentTree { std::vector mItems; // the root has index 1 static size_t GetParentIndex(size_t i) { return i/2; } static size_t GetLeftChildIndex(size_t i) { return i*2; } static size_t GetRightChildIndex(size_t i) { return GetLeftChildIndex(i)+1; } int mSize=0; int mBottomRowSize=0; size_t mFirstSingleItemIndex=0; struct cTraversalData { size_t i; int left_i, right_i; int left, right; cTraversalData(size_t i, int left_i, int right_i, int left, int right): i(i), left_i(left_i), right_i(right_i), left(max(left_i, left)), right(min(right_i, right)) { } cTraversalData Left() const { return cTraversalData(GetLeftChildIndex(i), left_i, (left_i+right_i)/2, left, right); } cTraversalData Right() const { return cTraversalData(GetRightChildIndex(i), (left_i+right_i)/2+1, right_i, left, right); } }; cTraversalData CreateTraversalData(int left, int right) const { return cTraversalData(1, 0, mBottomRowSize-1, left, right); } int InternalQueryInterval(const cTraversalData &TraversalData); void InternalIncreaseRange(const cTraversalData &TraversalData, int added); void InternalSetValue(const cTraversalData &TraversalData, int value); void PushLazy(const cTraversalData &TraversalData, int lazy_add); public: void Init(int Size); void IncreaseRange(int left, int right, int added); int QueryInterval(int left, int right); void SetValue(int item, int value); void MergerFunction(cSegmentData &result, const cSegmentData &sub_a, const cSegmentData &sub_b) { result.max_value=max(sub_a.max_value+sub_a.lazy_add, sub_b.max_value+sub_b.lazy_add); } }; void cSegmentTree::Init(int Size) { mSize=Size; int SizeRequired=Size==1?2:2*((int)ones_up_till_highest_bit(Size-1)+1); mItems.resize(SizeRequired); mFirstSingleItemIndex=SizeRequired/2; mBottomRowSize=SizeRequired/2; for(int i=(int)mFirstSingleItemIndex; i0; --i) { mItems[i].length=mItems[GetLeftChildIndex(i)].length*2; mItems[i].first_index=mItems[GetLeftChildIndex(i)].first_index; } // for(size_t i=mFirstSingleItemIndex-1; i>0; --i) // { // MergerFunction(mItems[i], mItems[GetLeftChildIndex(i)], mItems[GetRightChildIndex(i)]); // } } int cSegmentTree::InternalQueryInterval(const cTraversalData &TraversalData) { auto &item=mItems[TraversalData.i]; if(TraversalData.left_i>=TraversalData.left&&TraversalData.right_i<=TraversalData.right) { return item.max_value+item.lazy_add; } if(item.lazy_add) { PushLazy(TraversalData.Left(), item.lazy_add); PushLazy(TraversalData.Right(), item.lazy_add); item.lazy_add=0; } int middle=(TraversalData.left_i+TraversalData.right_i)/2; int result=0; if(middle>=TraversalData.left) result=InternalQueryInterval(TraversalData.Left()); if(middle=TraversalData.left&&TraversalData.right_i<=TraversalData.right) { item.lazy_add+=add; return; } if(item.lazy_add) { PushLazy(TraversalData.Left(), item.lazy_add); PushLazy(TraversalData.Right(), item.lazy_add); item.lazy_add=0; } int middle=(TraversalData.left_i+TraversalData.right_i)/2; if(middle>=TraversalData.left) InternalIncreaseRange(TraversalData.Left(), add); if(middle=TraversalData.left&&TraversalData.right_i<=TraversalData.right) { item.max_value=value; item.lazy_add=0; return; } if(item.lazy_add) { PushLazy(TraversalData.Left(), item.lazy_add); PushLazy(TraversalData.Right(), item.lazy_add); item.lazy_add=0; } int middle=(TraversalData.left_i+TraversalData.right_i)/2; if(middle>=TraversalData.left) InternalSetValue(TraversalData.Left(), value); if(middle sources[2]; }; vector zoos; unique_ptr st[2]; void CalculateBest(int zi) { cZoo& zoo=zoos[zi]; int best=0;// zi?zoos[zi-1].best:0; for(int type=0; type<2; ++type) { cSegmentTree& seg_tree=*st[type]; for(auto s: zoo.sources[type]) { seg_tree.IncreaseRange(0, s, 1); } if(zi) best=max(best, seg_tree.QueryInterval(0, zi-1)); } for(int type=0; type<2; ++type) { st[type]->SetValue(zi, best); } zoo.best=best; } void Solve() { // delivered_sources[0].clear(); // delivered_sources[1].clear(); RII(zoo_count, animal_count); for(int type=0; type<2; ++type) { st[type]=make_unique(); st[type]->Init(zoo_count); } zoos.clear(); zoos.resize(zoo_count); vector types(animal_count); vector sources(animal_count); char buf[100]; for(auto& t : types) { scanf("%s", buf); t = (buf[0] == 'E' || buf[0] == 'C') ? 0 : 1; } for(auto& s : sources) { scanf("%d", &s); --s; } // int min_source = numeric_limits::max();; // int max_target = 0; FOR(i, animal_count) { RI(target); --target; int source = sources[i]; if(source < target) { // min_source = min(min_source, source); // max_target = max(max_target, d); zoos[target].sources[types[i]].push_back(source); } } for(int zi=0; zi best_so_far) { printf("%d ", i + 1); ++best_so_far; } if(best_here == animal_count) { printf("\n"); return; } } while(best_so_far < animal_count) { printf("-1 "); ++best_so_far; } printf("\n"); } int Init() { // states[0].reserve(50); // states[1].reserve(50); // delivered_sources[0].reserve(5'000'1); // delivered_sources[1].reserve(5'000'1); zoos.reserve(5'000'1); //int t=1; RI(t); return t; } int main() { // std::ios::sync_with_stdio(false); int t = Init(); for(int tc = 1; tc <= t; ++tc) { // printf("Case #%d: ", tc); Solve(); } }