fork(3) download
  1. #pragma GCC optimize ("O3")
  2. #pragma GCC target ("sse4")
  3.  
  4. #include <bits/stdc++.h>
  5.  
  6. using namespace std;
  7.  
  8. typedef double db;
  9. typedef long long ll;
  10. typedef long double ld;
  11. typedef string str;
  12.  
  13. typedef pair<int, int> pi;
  14. typedef pair<ll,ll> pl;
  15. typedef pair<ld,ld> pd;
  16. typedef complex<ld> cd;
  17.  
  18. typedef vector<int> vi;
  19. typedef vector<ll> vl;
  20. typedef vector<ld> vd;
  21. typedef vector<str> vs;
  22. typedef vector<pi> vpi;
  23. typedef vector<pl> vpl;
  24. typedef vector<cd> vcd;
  25.  
  26. #define FOR(i,a,b) for (int i = (a); i < (b); i++)
  27. #define F0R(i,a) FOR(i,0,a)
  28. #define ROF(i,a,b) for (int i = (b)-1; i >= (a); i--)
  29. #define R0F(i,a) ROF(i,0,a)
  30. #define trav(a,x) for (auto& a : x)
  31.  
  32. #define mp make_pair
  33. #define pb push_back
  34. #define eb emplace_back
  35. #define f first
  36. #define s second
  37. #define lb lower_bound
  38. #define ub upper_bound
  39.  
  40. #define sz(x) (int)x.size()
  41. #define all(x) begin(x), end(x)
  42. #define rall(x) rbegin(x), rend(x)
  43. #define rsz resize
  44. #define ins insert
  45.  
  46. const int MOD = 1e9+7; // 998244353 = (119<<23)+1
  47. const ll INF = 1e18;
  48. const int MX = 2e5+5;
  49. const ld PI = 4*atan((ld)1);
  50.  
  51. template<class T> bool ckmin(T& a, const T& b) { return a > b ? a = b, 1 : 0; }
  52. template<class T> bool ckmax(T& a, const T& b) { return a < b ? a = b, 1 : 0; }
  53.  
  54. mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
  55.  
  56. #include <ext/pb_ds/tree_policy.hpp>
  57. #include <ext/pb_ds/assoc_container.hpp>
  58. #include <ext/rope>
  59.  
  60. using namespace __gnu_pbds;
  61. using namespace __gnu_cxx;
  62.  
  63. template <class T> using Tree = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
  64.  
  65. #define ook order_of_key
  66. #define fbo find_by_order
  67.  
  68. namespace input {
  69. template<class T> void re(complex<T>& x);
  70. template<class T1, class T2> void re(pair<T1,T2>& p);
  71. template<class T> void re(vector<T>& a);
  72. template<class T, size_t SZ> void re(array<T,SZ>& a);
  73.  
  74. template<class T> void re(T& x) { cin >> x; }
  75. void re(double& x) { string t; re(t); x = stod(t); }
  76. void re(ld& x) { string t; re(t); x = stold(t); }
  77. template<class T, class... Ts> void re(T& t, Ts&... ts) {
  78. re(t); re(ts...);
  79. }
  80.  
  81. template<class T> void re(complex<T>& x) { T a,b; re(a,b); x = cd(a,b); }
  82. template<class T1, class T2> void re(pair<T1,T2>& p) { re(p.f,p.s); }
  83. template<class T> void re(vector<T>& a) { F0R(i,sz(a)) re(a[i]); }
  84. template<class T, size_t SZ> void re(array<T,SZ>& a) { F0R(i,SZ) re(a[i]); }
  85. }
  86.  
  87. using namespace input;
  88.  
  89. namespace output {
  90. void pr(int x) { cout << x; }
  91. void pr(long x) { cout << x; }
  92. void pr(ll x) { cout << x; }
  93. void pr(unsigned x) { cout << x; }
  94. void pr(unsigned long x) { cout << x; }
  95. void pr(unsigned long long x) { cout << x; }
  96. void pr(float x) { cout << x; }
  97. void pr(double x) { cout << x; }
  98. void pr(ld x) { cout << x; }
  99. void pr(char x) { cout << x; }
  100. void pr(const char* x) { cout << x; }
  101. void pr(const string& x) { cout << x; }
  102. void pr(bool x) { pr(x ? "true" : "false"); }
  103. template<class T> void pr(const complex<T>& x) { cout << x; }
  104.  
  105. template<class T1, class T2> void pr(const pair<T1,T2>& x);
  106. template<class T> void pr(const T& x);
  107.  
  108. template<class T, class... Ts> void pr(const T& t, const Ts&... ts) {
  109. pr(t); pr(ts...);
  110. }
  111. template<class T1, class T2> void pr(const pair<T1,T2>& x) {
  112. pr("{",x.f,", ",x.s,"}");
  113. }
  114. template<class T> void pr(const T& x) {
  115. pr("{"); // const iterator needed for vector<bool>
  116. bool fst = 1; for (const auto& a: x) pr(!fst?", ":"",a), fst = 0;
  117. pr("}");
  118. }
  119.  
  120. void ps() { pr("\n"); } // print w/ spaces
  121. template<class T, class... Ts> void ps(const T& t, const Ts&... ts) {
  122. pr(t); if (sizeof...(ts)) pr(" "); ps(ts...);
  123. }
  124.  
  125. void pc() { pr("]\n"); } // debug w/ commas
  126. template<class T, class... Ts> void pc(const T& t, const Ts&... ts) {
  127. pr(t); if (sizeof...(ts)) pr(", "); pc(ts...);
  128. }
  129. #define dbg(x...) pr("[",#x,"] = ["), pc(x);
  130. }
  131.  
  132. using namespace output;
  133.  
  134. namespace io {
  135. void setIn(string s) { freopen(s.c_str(),"r",stdin); }
  136. void setOut(string s) { freopen(s.c_str(),"w",stdout); }
  137. void setIO(string s = "") {
  138. cin.sync_with_stdio(0); cin.tie(0); // fast I/O
  139. cin.exceptions(cin.failbit); // ex. throws exception when you try to read letter into int
  140. if (sz(s)) { setIn(s+".in"), setOut(s+".out"); } // for USACO
  141. }
  142. }
  143.  
  144. using namespace io;
  145.  
  146. template<class T> T invGeneral(T a, T b) {
  147. a %= b; if (a == 0) return b == 1 ? 0 : -1;
  148. T x = invGeneral(b,a);
  149. return x == -1 ? -1 : ((1-(ll)b*x)/a+b)%b;
  150. }
  151.  
  152. template<class T> struct modular {
  153. T val;
  154. explicit operator T() const { return val; }
  155. modular() { val = 0; }
  156. modular(const ll& v) {
  157. val = (-MOD <= v && v <= MOD) ? v : v % MOD;
  158. if (val < 0) val += MOD;
  159. }
  160.  
  161. // friend ostream& operator<<(ostream& os, const modular& a) { return os << a.val; }
  162. friend void pr(const modular& a) { pr(a.val); }
  163. friend void re(modular& a) { ll x; re(x); a = modular(x); }
  164.  
  165. friend bool operator==(const modular& a, const modular& b) { return a.val == b.val; }
  166. friend bool operator!=(const modular& a, const modular& b) { return !(a == b); }
  167. friend bool operator<(const modular& a, const modular& b) { return a.val < b.val; }
  168.  
  169. modular operator-() const { return modular(-val); }
  170. modular& operator+=(const modular& m) { if ((val += m.val) >= MOD) val -= MOD; return *this; }
  171. modular& operator-=(const modular& m) { if ((val -= m.val) < 0) val += MOD; return *this; }
  172. modular& operator*=(const modular& m) { val = (ll)val*m.val%MOD; return *this; }
  173. friend modular pow(modular a, ll p) {
  174. modular ans = 1; for (; p; p /= 2, a *= a) if (p&1) ans *= a;
  175. return ans;
  176. }
  177. friend modular inv(const modular& a) {
  178. auto i = invGeneral(a.val,MOD); assert(i != -1);
  179. return i;
  180. } // equivalent to return exp(b,MOD-2) if MOD is prime
  181. modular& operator/=(const modular& m) { return (*this) *= inv(m); }
  182.  
  183. friend modular operator+(modular a, const modular& b) { return a += b; }
  184. friend modular operator-(modular a, const modular& b) { return a -= b; }
  185. friend modular operator*(modular a, const modular& b) { return a *= b; }
  186.  
  187. friend modular operator/(modular a, const modular& b) { return a /= b; }
  188. };
  189.  
  190. typedef modular<int> mi;
  191. typedef pair<mi,mi> pmi;
  192. typedef vector<mi> vmi;
  193. typedef vector<pmi> vpmi;
  194.  
  195.  
  196. int n,m,x,y, ans[605];
  197.  
  198. template<int SZ> struct Dinic {
  199. typedef ll F; // flow type
  200. struct Edge { int to, rev; F flow, cap; int id; };
  201.  
  202. int N,s,t;
  203. vector<Edge> adj[SZ];
  204. typename vector<Edge>::iterator cur[SZ];
  205. void addEdge(int u, int v, F cap, int id) {
  206. assert(cap >= 0); // don't try smth dumb
  207. Edge a{v, sz(adj[v]), 0, cap, id}, b{u, sz(adj[u]), 0, 0, 0};
  208. adj[u].pb(a), adj[v].pb(b);
  209. }
  210.  
  211. int level[SZ];
  212. bool bfs() { // level = shortest distance from source
  213. // after computing flow, edges {u,v} such that level[u] \neq -1, level[v] = -1 are part of min cut
  214. F0R(i,N) level[i] = -1, cur[i] = begin(adj[i]);
  215. queue<int> q({s}); level[s] = 0;
  216. while (sz(q)) {
  217. int u = q.front(); q.pop();
  218. trav(e,adj[u]) if (level[e.to] < 0 && e.flow < e.cap)
  219. q.push(e.to), level[e.to] = level[u]+1;
  220. }
  221. return level[t] >= 0;
  222. }
  223. F sendFlow(int v, F flow) {
  224. if (v == t) return flow;
  225. for (; cur[v] != end(adj[v]); cur[v]++) {
  226. Edge& e = *cur[v];
  227. if (level[e.to] != level[v]+1 || e.flow == e.cap) continue;
  228. auto df = sendFlow(e.to,min(flow,e.cap-e.flow));
  229. if (df) { // saturated at least one edge
  230. e.flow += df; adj[e.to][e.rev].flow -= df;
  231. return df;
  232. }
  233. }
  234. return 0;
  235. }
  236. F maxFlow(int _N, int _s, int _t) {
  237. N = _N, s = _s, t = _t; if (s == t) return -1;
  238. F tot = 0;
  239. while (bfs()) while (auto df = sendFlow(s,numeric_limits<F>::max())) tot += df;
  240. return tot;
  241. }
  242. void getPath(int label) {
  243. vi pre(N,-1);
  244. vector<Edge*> stor(N);
  245. queue<int> q; q.push(0);
  246. while (sz(q)) {
  247. auto a = q.front(); q.pop();
  248. trav(t,adj[a]) if (t.flow > 0 && pre[t.to] == -1) {
  249. pre[t.to] = a; stor[t.to] = &t;
  250. q.push(t.to);
  251. }
  252. }
  253. assert(pre[N-1] != -1);
  254. int cur = N-1;
  255. while (cur) {
  256. stor[cur]->flow --;
  257. if (stor[cur]->id) ans[stor[cur]->id] = label;
  258. cur = pre[cur];
  259. }
  260. }
  261. };
  262.  
  263. vpi lec[1205], sem[1205];
  264.  
  265. void solve() {
  266. re(n,m,x,y);
  267. vpi a(n), b(m); re(a,b);
  268. map<int,int> z;
  269. trav(t,a) z[t.f] = z[t.s] = 0;
  270. trav(t,b) z[t.f] = z[t.s] = 0;
  271. FOR(i,1,sz(z)+1) lec[i].clear(), sem[i].clear();
  272. int co = 0;
  273. trav(t,z) t.s = ++co;
  274. F0R(i,n) { auto t = a[i]; lec[z[t.f]].pb({z[t.s],i+1}); }
  275. F0R(i,m) { auto t = b[i]; sem[z[t.f]].pb({z[t.s],n+i+1}); }
  276. // have X at some point, Y at some point
  277. // at least Y-(x-X) must be dealt with
  278. // so at most min(y,y-(Y-(x-X))) not doing anything
  279. priority_queue<int,vi,greater<int>> LEC, SEM;
  280. int X = 0, Y = 0;
  281. Dinic<1205> D;
  282. F0R(i,sz(z)+1) {
  283. X += sz(lec[i]); Y += sz(sem[i]);
  284. trav(t,lec[i]) LEC.push(t.f);
  285. trav(t,sem[i]) {
  286. SEM.push(t.f);
  287. D.addEdge(i,t.f,1,t.s);
  288. }
  289. while (sz(LEC) && LEC.top() == i) { X --; LEC.pop(); }
  290. while (sz(SEM) && SEM.top() == i) { Y --; SEM.pop(); }
  291. if (X > x || X+Y > x+y) {
  292. ps("NO");
  293. return;
  294. }
  295. D.addEdge(i,i+1,min(y,x+y-X-Y),0);
  296. }
  297. assert(X == 0 && Y == 0);
  298. if (D.maxFlow(sz(z)+2,0,sz(z)+1) != y) { ps("NO"); return; }
  299. FOR(i,1,n+m+1) ans[i] = 0;
  300. FOR(i,x+1,x+y+1) D.getPath(i);
  301. vector<pair<pi,int>> dumb; vi hd;
  302. FOR(i,1,n+m+1) if (!ans[i]) {
  303. if (i <= n) dumb.pb({a[i-1],i});
  304. else dumb.pb({b[i-n-1],i});
  305. }
  306. FOR(i,1,x+1) hd.pb(i);
  307. sort(all(dumb));
  308. priority_queue<pi,vpi,greater<pi>> lef;
  309. trav(t,dumb) {
  310. while (sz(lef) && lef.top().f <= t.f.f) {
  311. hd.pb(lef.top().s);
  312. lef.pop();
  313. }
  314. assert(sz(hd));
  315. ans[t.s] = hd.back();
  316. lef.push({t.f.s,hd.back()}); hd.pop_back();
  317. }
  318. ps("YES");
  319. FOR(i,1,n+m+1) pr(ans[i],' ');
  320. ps();
  321. }
  322.  
  323. int main() {
  324. setIO(); int t; re(t);
  325. F0R(i,t) solve();
  326. // you should actually read the stuff at the bottom
  327. }
  328.  
  329. /* stuff you should look for
  330. * int overflow, array bounds
  331. * special cases (n=1?), set tle
  332. * do smth instead of nothing and stay organized
  333. */
  334.  
Success #stdin #stdout 0s 4380KB
stdin
3
1 2 1 1
3 4
2 4
1 3
3 4 2 3
5 7
1 3
1 7
4 8
2 5
1 6
2 8
0 1 1 0
1 1000000
stdout
YES
1 2 1 
NO
YES
1