A. Circuits
问题等价于线段和直线的相交问题。设两条直线分别是y=a和y=b。先把n条线段都塞进线段树。枚举a的时候,把和y=a相交的线段都从线段树里去掉,线段树上保留不和a相交的线段,然后查全局最大值。
#include<bits/stdc++.h>
#define pb push_back
#define fi first
#define se second
#define sz(x) (int)x.size()
#define cl(x) x.clear()
#define all(x) x.begin() , x.end()
#define rep(i , x , n) for(int i = x ; i <= n ; i ++)
#define per(i , n , x) for(int i = n ; i >= x ; i --)
#define mem0(x) memset(x , 0 , sizeof(x))
#define mem_1(x) memset(x , -1 , sizeof(x))
#define mem_inf(x) memset(x , 0x3f , sizeof(x))
#define debug(x) cerr << #x << " = " << x << '\n'
#define ddebug(x , y) cerr << #x << " = " << x << " " << #y << " = " << y << '\n'
#define ios std::ios::sync_with_stdio(false) , cin.tie(0)
using namespace std ;
typedef long long ll ;
typedef long double ld ;
typedef pair<int , int> pii ;
typedef pair<ll , ll> pll ;
typedef double db ;
const int mod = 998244353 ;
const int maxn = 4e5 + 10 ;
const int inf = 0x3f3f3f3f ;
const double eps = 1e-6 ;
int n , c[maxn] ;
int nxt[maxn] , lst[maxn] ;
struct node
{
int x , y , f ;
int id ;
bool operator < (const node &s) const
{
return x < s.x ;
}
} a[maxn] ;
bool cmp(node s , node t)
{
if(s.id != t.id) return s.id < t.id ;
else return s.f > t.f ;
}
struct seg_tree
{
int max1[maxn << 2] , lazy[maxn << 2] ;
int ls(int x){ return x << 1 ; }
int rs(int x){ return x << 1 | 1 ; }
void push_up(int p){ max1[p] = max(max1[ls(p)] , max1[rs(p)]) ; }
void build(int id , int l , int r)
{
lazy[id] = 0 ;
if(l == r) {max1[id] = c[l] ; return ;}
int mid = (l + r) >> 1 ;
build(ls(id) , l , mid) ;
build(rs(id) , mid + 1 , r) ;
push_up(id) ;
}
void f(int id , int l , int r , int k)
{
lazy[id] += k ;
max1[id] += k ;
}
void push_down(int id , int l , int r)
{
int mid = (l + r) >> 1 ;
f(ls(id) , l , mid , lazy[id]) ;
f(rs(id) , mid + 1 , r , lazy[id]) ;
lazy[id] = 0 ;
}
void add(int id , int l , int r , int x , int y , int k)
{
if(x > y || x > r || y < l) return ;
if(x <= l && r <= y)
{
max1[id] += k ;
lazy[id] += k ;
return ;
}
push_down (id , l , r) ;
int mid = (l + r) >> 1 ;
if(x <= mid) add(ls(id) , l , mid , x , y , k) ;
if(y > mid) add(rs(id) , mid + 1 , r , x , y , k) ;
push_up(id) ;
}
int query(int id , int l , int r , int x , int y)
{
if(x > y || x > r || y < l) return inf ;
int ans = 0 ;
if(x <= l && r <= y) return max1[id] ;
int mid = (l + r) >> 1 ;
push_down(id , l , r) ;
if(x <= mid) ans = max(ans , query(ls(id) , l , mid , x , y)) ;
if(y > mid) ans = max(ans , query(rs(id) , mid + 1 , r , x , y)) ;
return ans ;
}
} seg ;
int main()
{
ios ;
cin >> n ;
rep(i , 1 , n)
{
int u1 , v1 , u2 , v2 ;
cin >> u1 >> v1 >> u2 >> v2 ;
a[i * 2 - 1].x = v2 ;
a[i * 2 - 1].f = 1 ;
a[i * 2 - 1].id = i ;
a[i * 2].x = v1 + 1 ;
a[i * 2].f = -1 ;
a[i * 2].id = i ;
}
sort(a + 1 , a + 2 * n + 1) ;
int now = 0 ;
rep(i , 1 , 2 * n)
{
now ++ ;
int j = i ;
while(j + 1 <= 2 * n && a[j + 1].x == a[j].x) j ++ ;
rep(k , i , j) a[k].y = now ;
i = j ;
}
sort(a + 1 , a + 2 * n + 1 , cmp) ;
rep(i , 1 , n) nxt[i] = a[i * 2].y , lst[i] = a[i * 2 - 1].y ;
rep(i , 1 , n * 2) c[a[i].y] += a[i].f ;
rep(i , 1 , now) c[i] += c[i - 1] ;
rep(i , 1 , now) seg.add(1 , 1 , now , i , i , c[i]) ;//, ddebug(i , c[i]) ;
sort(a + 1 , a + 2 * n + 1) ;
int res = 0 ;
int ans = 0 ;
rep(i , 1 , 2 * n)
{
int j = i ;
while(j + 1 <= 2 * n && a[j + 1].y == a[j].y) j ++ ;
rep(k , i , j)
{
res += a[k].f ;
if(a[k].f == -1) seg.add(1 , 1 , now , lst[a[k].id] , a[k].y - 1 , 1) ;
else seg.add(1 , 1 , now , a[k].y , nxt[a[k].id] - 1 , -1) ;
}
i = j ;
ans = max(ans , res + seg.max1[1]) ;
//ddebug(a[i].y , res + seg.max1[1]) ;
}
cout << ans << '\n' ;
return 0 ;
}
B. Cosmetic Survey
题意转化一下就是最大化a到b的路径上的边的最小值。floyd即可。
#include<bits/stdc++.h>
#define pb push_back
#define fi first
#define se second
#define sz(x) (int)x.size()
#define cl(x) x.clear()
#define all(x) x.begin() , x.end()
#define rep(i , x , n) for(int i = x ; i <= n ; i ++)
#define per(i , n , x) for(int i = n ; i >= x ; i --)
#define mem0(x) memset(x , 0 , sizeof(x))
#define mem_1(x) memset(x , -1 , sizeof(x))
#define mem_inf(x) memset(x , 0x3f , sizeof(x))
#define debug(x) cerr << #x << " = " << x << '\n'
#define ddebug(x , y) cerr << #x << " = " << x << " " << #y << " = " << y << '\n'
#define ios std::ios::sync_with_stdio(false) , cin.tie(0)
using namespace std ;
typedef long long ll ;
typedef long double ld ;
typedef pair<int , int> pii ;
typedef pair<ll , ll> pll ;
typedef double db ;
const int mod = 998244353 ;
const int maxn = 500 + 10 ;
const int inf = 0x3f3f3f3f ;
const double eps = 1e-6 ;
int m , n ;
int c[maxn][maxn] ;
int d[maxn][maxn] ;
int s[maxn][maxn] ;
bool vis[maxn] ;
vector<pii> g[maxn] ;
int main()
{
ios ;
cin >> m >> n ;
rep(i , 1 , n) rep(j , 1 , m) cin >> c[i][j] ;
rep(i , 1 , n) rep(j , 1 , m) if(c[i][j] == 0) c[i][j] = 1e7 ;
rep(i , 1 , m) rep(j , 1 , m)
{
int x = 0 , y = 0 ;
rep(k , 1 , n) if(c[k][i] < c[k][j]) x ++ ; else if(c[k][j] < c[k][i]) y ++ ;
if(x > y) d[i][j] = x ;
else if(x < y) d[j][i] = y ;
}
rep(k , 1 , m) rep(i , 1 , m) rep(j , 1 , m) d[i][j] = max(d[i][j] , min(d[i][k] , d[k][j])) ;
rep(i , 1 , m)
{
bool flag = 1 ;
rep(j , 1 , m) if(j != i && d[i][j] < d[j][i]) flag = 0 ;
if(flag) cout << i << ' ' ;
}
cout << '\n' ;
return 0 ;
}
D. Go Latin
模拟。
#include<bits/stdc++.h>
#define pb push_back
#define fi first
#define se second
#define sz(x) (int)x.size()
#define cl(x) x.clear()
#define all(x) x.begin() , x.end()
#define rep(i , x , n) for(int i = x ; i <= n ; i ++)
#define per(i , n , x) for(int i = n ; i >= x ; i --)
#define mem0(x) memset(x , 0 , sizeof(x))
#define mem_1(x) memset(x , -1 , sizeof(x))
#define mem_inf(x) memset(x , 0x3f , sizeof(x))
#define debug(x) cerr << #x << " = " << x << '\n'
#define ddebug(x , y) cerr << #x << " = " << x << " " << #y << " = " << y << '\n'
#define ios std::ios::sync_with_stdio(false) , cin.tie(0)
using namespace std ;
typedef long long ll ;
typedef long double ld ;
typedef pair<int , int> pii ;
typedef pair<ll , ll> pll ;
typedef double db ;
const int mod = 998244353 ;
const int maxn = 2e5 + 10 ;
const int inf = 0x3f3f3f3f ;
const double eps = 1e-6 ;
char s[maxn] ;
map<string , string> id ;
void init()
{
id["a"] = "as" ;
id["i"] = "ios" , id["y"] = "ios" ;
id["l"] = "les" ;
id["n"] = "anes" , id["ne"] = "anes" ;
id["o"] = "os" ;
id["r"] = "res" ;
id["t"] = "tas" ;
id["u"] = "us" ;
id["v"] = "ves" ;
id["w"] = "was" ;
}
void solve()
{
int len ;
cin >> s + 1 ;
len = strlen(s + 1) ;
if(len >= 1)
{
string t = "" ;
t += s[len] ;
if(id.count(t))
{
rep(i , 1 , len - 1) cout << s[i] ;
cout << id[t] << '\n' ;
return ;
}
}
if(len >= 2)
{
string t = "" ;
t += s[len - 1] ;
t += s[len] ;
if(id.count(t))
{
rep(i , 1 , len - 2) cout << s[i] ;
cout << id[t] << '\n' ;
return ;
}
}
rep(i , 1 , len) cout << s[i] ;
cout << "us\n" ;
}
int main()
{
ios ;
init() ;
int T ;
cin >> T ;
while(T --) solve() ;
return 0 ;
}
E. LED
二分答案。check(t)的时候模拟整个过程,如果产生的区间多于3个,就放大t,否则缩小t。
坑点:1.double会卡常数,所以要用longlong 2.a[i].x=0时答案最少是a[i].y
#include<bits/stdc++.h>
#define pb push_back
#define fi first
#define se second
#define sz(x) (int)x.size()
#define cl(x) x.clear()
#define all(x) x.begin() , x.end()
#define rep(i , x , n) for(int i = x ; i <= n ; i ++)
#define per(i , n , x) for(int i = n ; i >= x ; i --)
#define mem0(x) memset(x , 0 , sizeof(x))
#define mem_1(x) memset(x , -1 , sizeof(x))
#define mem_inf(x) memset(x , 0x3f , sizeof(x))
#define debug(x) cerr << #x << " = " << x << '\n'
#define ddebug(x , y) cerr << #x << " = " << x << " " << #y << " = " << y << '\n'
#define ios std::ios::sync_with_stdio(false) , cin.tie(0)
using namespace std ;
typedef long long ll ;
typedef long double ld ;
typedef pair<int , int> pii ;
typedef pair<ll , ll> pll ;
typedef double db ;
const int mod = 998244353 ;
const int maxn = 3e5 + 10 ;
const int inf = 0x3f3f3f3f ;
const double eps = 1e-6 ;
int n ;
struct node
{
ll x , y ;
bool operator < (const node &s) const
{
return x < s.x ;
}
} a[maxn] ;
bool ok(ll t)
{
int tmp1 = 0 , tmp2 = 0 , tmp3 = 0 ;
rep(i , 1 , n) if(a[i].y <= t) tmp1 = i ; else break ;
if(tmp1 == n) return 1 ;
ll mn = 1e10 , mx = 0 ;
ll l1 = 0 , l2 = 0 ;
rep(i , tmp1 + 1 , n)
{
mn = min(mn , a[i].y) ;
mx = max(mx , a[i].y) ;
if(mx - mn <= 2 * t) tmp2 = i ;
else break ;
}
if(tmp2 == 0) return 0 ;
if(tmp2 == n) return 1 ;
l1 = (mx + mn) / 2 ;
mn = 1e10 , mx = 0 ;
rep(i , tmp2 + 1 , n)
{
mn = min(mn , a[i].y) ;
mx = max(mx , a[i].y) ;
if(mx - mn <= 2 * t) tmp3 = i ;
else break ;
}
l2 = (mx + mn) / 2 ;
if(tmp3 != n || l1 > l2) return 0 ;
return 1 ;
}
int main()
{
ios ;
ll base = 0 ;
cin >> n ;
rep(i , 1 , n) cin >> a[i].x >> a[i].y , a[i].y *= 10 ;
rep(i , 1 , n) if(a[i].x == 0) base = max(base , a[i].y) ;
sort(a + 1 , a + n + 1) ;
ll l = 0 , r = 1e10 ;
ll ans = 0 ;
while(l <= r)
{
ll mid = (l + r) / 2 ;
if(ok(mid)) ans = mid , r = mid - 1 ;
else l = mid + 1 ;
}
ans = max(ans , base) ;
cout << ans / 10 << '.' << ans % 10 << '\n' ;
return 0 ;
}
F. Parentheses
因为串长只有1000,所以可以n^2去做。直接模拟递归的过程,因为递归的底部是(a+b),所以遇到(a+b)就变成a。
#include<bits/stdc++.h>
#define pb push_back
#define fi first
#define se second
#define sz(x) (int)x.size()
#define cl(x) x.clear()
#define all(x) x.begin() , x.end()
#define rep(i , x , n) for(int i = x ; i <= n ; i ++)
#define per(i , n , x) for(int i = n ; i >= x ; i --)
#define mem0(x) memset(x , 0 , sizeof(x))
#define mem_1(x) memset(x , -1 , sizeof(x))
#define mem_inf(x) memset(x , 0x3f , sizeof(x))
#define debug(x) cerr << #x << " = " << x << '\n'
#define ddebug(x , y) cerr << #x << " = " << x << " " << #y << " = " << y << '\n'
#define ios std::ios::sync_with_stdio(false) , cin.tie(0)
using namespace std ;
typedef long long ll ;
typedef long double ld ;
typedef pair<int , int> pii ;
typedef pair<ll , ll> pll ;
typedef double db ;
const int mod = 998244353 ;
const int maxn = 2e5 + 10 ;
const int inf = 0x3f3f3f3f ;
const double eps = 1e-6 ;
int len = 0 , len2 ;
char s[maxn] , t[maxn] ;
int main()
{
ios ;
s[len ++] = '(' ;
while(1)
{
char c = getchar() ;
if(c == ' ') continue ;
if(c == '\n') break ;
if(isalpha(c)) s[len ++] = 'a' ;
else if(c == '(' || c == ')') s[len ++] = c ;
else s[len ++] = '+' ;
}
s[len ++] = ')' ;
bool is_improper = 0 ;
rep(i , 1 , 1000)
{
len2 = 0 ;
//debug(len) ;
rep(j , 0 , len - 1)
{
//debug(j) ;
if(j + 2 <= len - 1)
{
if(s[j] == '(' && s[j + 1] == 'a' && s[j + 2] == ')' || s[j] == 'a' && s[j + 1] == '+' && s[j + 2] == 'a')
{
j += 2 ;
t[len2 ++] = 'a' ;
is_improper = 1 ;
continue ;
}
}
if(j + 4 <= len - 1)
{
if(s[j] == '(' && s[j + 1] == 'a' && s[j + 2] == '+' && s[j + 3] == 'a' && s[j + 4] == ')')
{
j += 4 ;
t[len2 ++] = 'a' ;
continue ;
}
}
t[len2 ++] = s[j] ;
//if(i == 2) debug(11111) , ddebug(s[j] , t[len2 - 1]) ;
}
//debug(t[0]) ;
rep(j , 0 , len2 - 1) s[j] = t[j] ;
//debug(s[0]) ;
len = len2 ;
}
//debug(len) ;
if(len > 1 || len == 1 && s[0] != 'a') cout << "error\n" ;
else if(is_improper) cout << "improper\n" ;
else cout << "proper\n" ;
return 0 ;
}
G. Secret Code
#include<bits/stdc++.h>
#define pb push_back
#define fi first
#define se second
#define sz(x) (int)x.size()
#define cl(x) x.clear()
#define all(x) x.begin() , x.end()
#define rep(i , x , n) for(int i = x ; i <= n ; i ++)
#define per(i , n , x) for(int i = n ; i >= x ; i --)
#define mem0(x) memset(x , 0 , sizeof(x))
#define mem_1(x) memset(x , -1 , sizeof(x))
#define mem_inf(x) memset(x , 0x3f , sizeof(x))
#define debug(x) cerr << #x << " = " << x << '\n'
#define ddebug(x , y) cerr << #x << " = " << x << " " << #y << " = " << y << '\n'
#define ios std::ios::sync_with_stdio(false) , cin.tie(0)
using namespace std ;
typedef long long ll ;
typedef long double ld ;
typedef pair<int , int> pii ;
typedef pair<ll , ll> pll ;
typedef double db ;
const int mod = 998244353 ;
const int maxn = 2e5 + 10 ;
const int inf = 0x3f3f3f3f ;
const double eps = 1e-11 ;
int n ;
struct node
{
db s , wa , wb , wc ;
int id ;
db p ;
bool operator < (const node &s) const
{
if(fabs(p - s.p) > eps) return p < s.p ;
else return id < s.id ;
}
} a[maxn] ;
void solve(int i)
{
db s = a[i].s ;
db wa = a[i].wa ;
db wb = a[i].wb ;
db wc = a[i].wc ;
db res = 0 ;
res += (s - (wa + wb) / 2) * wa * wb ;
res += (s - (wb + wc) / 2) * wb * wc ;
res += (s - (wa + wc) / 2) * wa * wc ;
res /= s * s * s ;
a[i].p = res ;
}
int main()
{
ios ;
cin >> n ;
rep(i , 1 , n) cin >> a[i].s >> a[i].wa >> a[i].wb >> a[i].wc , a[i].id = i ;
rep(i , 1 , n) solve(i) ;
sort(a + 1 , a + n + 1) ;
// cout << a[1].p << '\n' ;
// cout << a[2].p << '\n' ;
rep(i , 1 , n) cout << a[i].id << " \n"[i == n] ;
return 0 ;
}
J. Starwars
两个人从军事基地出发,看看能不能在产生字符串相同的情况下分别到达人类控制和非人类控制的行星。反向bfs维护vis[][]。vis[i][j]=1表示可以一个人到达i另一个人到达j。
#include<bits/stdc++.h>
#define pb push_back
#define fi first
#define se second
#define sz(x) (int)x.size()
#define cl(x) x.clear()
#define all(x) x.begin() , x.end()
#define rep(i , x , n) for(int i = x ; i <= n ; i ++)
#define per(i , n , x) for(int i = n ; i >= x ; i --)
#define mem0(x) memset(x , 0 , sizeof(x))
#define mem_1(x) memset(x , -1 , sizeof(x))
#define mem_inf(x) memset(x , 0x3f , sizeof(x))
#define debug(x) cerr << #x << " = " << x << '\n'
#define ddebug(x , y) cerr << #x << " = " << x << " " << #y << " = " << y << '\n'
#define ios std::ios::sync_with_stdio(false) , cin.tie(0)
using namespace std ;
typedef long long ll ;
typedef long double ld ;
typedef pair<int , int> pii ;
typedef pair<ll , ll> pll ;
typedef double db ;
const int mod = 998244353 ;
const int maxn = 1e3 + 10 ;
const int inf = 0x3f3f3f3f ;
const double eps = 1e-6 ;
int n , w , c , h , m ;
bool H[maxn] ;
bool M[maxn] ;
vector<pii> g[maxn] ;
bool vis[maxn][maxn] ;
int main()
{
ios ;
cin >> n >> w >> c >> h >> m ;
rep(i , 1 , h)
{
int x ;
cin >> x ;
x ++ ;
H[x] = 1 ;
}
rep(i , 1 , m)
{
int x ;
cin >> x ;
x ++ ;
M[x] = 1 ;
}
rep(i , 1 , w)
{
int u , v , w ;
cin >> u >> w >> v ;
u ++ , v ++ ;
g[v].pb({u , w}) ;
}
queue<pii> q ;
rep(i , 1 , n) rep(j , 1 , n) if(M[i] && M[j]) q.push({i , j}) , vis[i][j] = 1 ;
while(!q.empty())
{
pii u = q.front() ;
q.pop() ;
int x = u.fi ;
int y = u.se ;
for(auto s : g[x]) for(auto t : g[y])
{
int nxt_x = s.fi ;
int nxt_y = t.fi ;
if(!vis[nxt_x][nxt_y] && s.se == t.se)
{
vis[nxt_x][nxt_y] = 1 ;
q.push({nxt_x , nxt_y}) ;
}
}
}
rep(i , 1 , n) rep(j , 1 , n) if(vis[i][j] && H[i] && !H[j]) { cout << "YES\n" ; return 0 ; }
cout << "NO\n" ;
return 0 ;
}
K. TV Show Game
3个位置中,一个错误会导致另外两个正确。跑2-sat。
#include<bits/stdc++.h>
#define pb push_back
#define fi first
#define se second
#define sz(x) (int)x.size()
#define cl(x) x.clear()
#define all(x) x.begin() , x.end()
#define rep(i , x , n) for(int i = x ; i <= n ; i ++)
#define per(i , n , x) for(int i = n ; i >= x ; i --)
#define mem0(x) memset(x , 0 , sizeof(x))
#define mem_1(x) memset(x , -1 , sizeof(x))
#define mem_inf(x) memset(x , 0x3f , sizeof(x))
#define debug(x) cerr << #x << " = " << x << '\n'
#define ddebug(x , y) cerr << #x << " = " << x << " " << #y << " = " << y << '\n'
#define ios std::ios::sync_with_stdio(false) , cin.tie(0)
using namespace std ;
typedef long long ll ;
typedef long double ld ;
typedef pair<int , int> pii ;
typedef pair<ll , ll> pll ;
typedef double db ;
const int mod = 998244353 ;
const int maxn = 2e5 + 10 ;
const int inf = 0x3f3f3f3f ;
const double eps = 1e-6 ;
int n , m ;
int a[5] , b[5] ;
char c[5] ;
vector<int> g[maxn] ;
struct Tarjan
{
int cnt , scc_num , lay ;
int low[maxn] , dfn[maxn] , belong[maxn] ;
int st[maxn] , s[maxn] ;
bool vis[maxn] ;
void init()
{
cnt = scc_num = lay = 0 ;
memset(vis , 0 , sizeof(vis)) ;
memset(low , 0 , sizeof(low)) ;
}
void dfs(int k)
{
vis[k] = 1 ;
low[k] = dfn[k] = ++ lay ;
st[++ cnt] = k ;
for(auto v : g[k])
{
if(dfn[v] == 0)
{
dfs(v) ;
low[k] = min(low[k] , low[v]) ;
}
else if(vis[v])
low[k] = min(low[k] , dfn[v]) ;
}
if(dfn[k] == low[k])
{
++ scc_num ;
do
{
belong[st[cnt]] = scc_num ;
vis[st[cnt]] = 0 ;
cnt -- ;
} while(st[cnt + 1] != k) ;
}
}
void cal()
{
for(int i = 1 ; i <= n * 2 ; i ++) if(dfn[i] == 0) dfs(i) ;
rep(i , 1 , n) if(belong[i] == belong[i + n]) { cout << "-1\n" ; return ; }
rep(i , 1 , n) if(belong[i] < belong[i + n]) cout << 'B' ; else cout << 'R' ;
cout << '\n' ;
}
} tarjan ;
int main()
{
ios ;
cin >> n >> m ;
rep(i , 1 , m)
{
rep(j , 1 , 3)
{
cin >> a[j] ;
cin >> c ;
if(c[0] == 'B') b[j] = 0 ;
else b[j] = 1 ;
}
g[a[1] + (1 - b[1]) * n].pb(a[2] + n * b[2]) ;
g[a[1] + (1 - b[1]) * n].pb(a[3] + n * b[3]) ;
g[a[2] + (1 - b[2]) * n].pb(a[1] + n * b[1]) ;
g[a[2] + (1 - b[2]) * n].pb(a[3] + n * b[3]) ;
g[a[3] + (1 - b[3]) * n].pb(a[1] + n * b[1]) ;
g[a[3] + (1 - b[3]) * n].pb(a[2] + n * b[2]) ;
}
tarjan.cal() ;
return 0 ;
}
L. Working Plan
每天优先用剩余工作天数最多的人,这样可以使后面安排更加灵活。有一些细节特判。
#include<bits/stdc++.h>
#define pb push_back
#define fi first
#define se second
#define sz(x) (int)x.size()
#define cl(x) x.clear()
#define all(x) x.begin() , x.end()
#define rep(i , x , n) for(int i = x ; i <= n ; i ++)
#define per(i , n , x) for(int i = n ; i >= x ; i --)
#define mem0(x) memset(x , 0 , sizeof(x))
#define mem_1(x) memset(x , -1 , sizeof(x))
#define mem_inf(x) memset(x , 0x3f , sizeof(x))
#define debug(x) cerr << #x << " = " << x << '\n'
#define ddebug(x , y) cerr << #x << " = " << x << " " << #y << " = " << y << '\n'
#define ios std::ios::sync_with_stdio(false) , cin.tie(0)
using namespace std ;
typedef long long ll ;
typedef long double ld ;
typedef pair<int , int> pii ;
typedef pair<ll , ll> pll ;
typedef double db ;
const int mod = 998244353 ;
const int maxn = 2e3 + 10 ;
const int inf = 0x3f3f3f3f ;
const double eps = 1e-6 ;
int m , n , w , h ;
priority_queue<pii> q ;
int W[maxn] , d[maxn] ;
vector<int> ans[maxn] ;
int c[maxn] ;
int lst[maxn] ;
bool vis[maxn] ;
int main()
{
ios ;
cin >> m >> n >> w >> h ;
int sum = 0 ;
rep(i , 1 , m) cin >> W[i] , lst[i] = -100000 , sum -= W[i] ;
rep(i , 1 , n) cin >> d[i] , sum += d[i] ;
if(sum != 0)
{
cout << "-1\n" ;
return 0 ;
}
rep(i , 1 , n)
{
rep(j , 1 , m) if(W[j] > 0 && lst[j] + h < i && !vis[j]) q.push({W[j] , j}) , vis[j] = 1 ;
c[i] += c[i - 1] ;
if(c[i] > d[i])
{
cout << "-1\n" ;
return 0 ;
}
int res = d[i] - c[i] ;
while(!q.empty())
{
if(res == 0) break ;
pii x = q.top() ;
q.pop() ;
vis[x.se] = 0 ;
ans[x.se].pb(i) ;
lst[x.se] = i + w - 1 ;
W[x.se] -= w ;
c[i] ++ ;
c[i + w] -- ;
res -- ;
}
if(res != 0)
{
cout << "-1\n" ;
return 0 ;
}
}
cout << "1\n" ;
rep(i , 1 , m)
{
for(auto x : ans[i]) cout << x << ' ' ;
cout << '\n' ;
}
return 0 ;
}