2022.10.15
这个系列记录各种单人vp/组队vp省赛or外国区域赛的内容。
也基本和之前一样只有简要解释和ac代码。
A. Finding Maximal Non-Trivial Monotones
求有多少个A边上有A,直接写就好了
#include <bits/stdc++.h>
#define int long long
#define endl '\n'
using namespace std;
const int N = 1e5 + 10;
int a[N];
inline void solve(){
int n = 0; cin >> n;
string s; cin >> s, s = '@' + s;
int cnt = 0, ans = 0;
for(int i = 1; i <= n; i++){
if(s[i] == 'a') cnt++;
else{
if(cnt >= 2) ans += cnt;
cnt = 0;
}
}
if(cnt >= 2) ans += cnt;
cout << ans << endl;
}
signed main(){
ios_base::sync_with_stdio(false), cin.tie(0);
int t = 1; // cin >> t;
while(t--) solve();
return 0;
}
B. Fun with Stones
三堆石子的尼姆游戏,每堆石子一定是在某个范围中随机选择,求Alice胜利的概率。
首先容易转化为求
a
∈
[
l
1
,
r
1
]
&
&
b
∈
[
l
2
,
r
2
]
&
&
c
∈
[
l
3
,
r
3
]
&
&
a
⊕
b
⊕
c
=
0
a \in [l_1,r_1] \&\& b \in [l_2,r_2] \&\& c \in [l_3,r_3] \&\& a \oplus b \oplus c =0
a∈[l1,r1]&&b∈[l2,r2]&&c∈[l3,r3]&&a⊕b⊕c=0。然后发现对于三个都处于该区间的条件是可以通过容斥出来的。
考虑做8次数位dp,每次都是满足
a
≤
x
&
&
b
≤
y
&
&
c
≤
z
a \leq x\&\& b \leq y \&\& c \leq z
a≤x&&b≤y&&c≤z 的三个数异或为0的方案数直接做数位dp即可。
一个简单的数位dp方式是,从低位到高位考虑,按照三个数的后缀小于等于限制或大于可以分成八种情况。在考虑每一位的方案时发现只有四种情况,考虑四种情况和限制对大小的影响即可。
#include <bits/stdc++.h>
#pragma gcc optimize("O2")
#pragma g++ optimize("O2")
#define int long long
#define endl '\n'
using namespace std;
const int N = 2e5 + 10, mod = 1e9 + 7;
int l1,r1,l2,r2,l3,r3;
int dp[40][10];
int way[]={0,3,5,6};
int qpow(int x,int y,int res=1){
for(;y;y>>=1,(x*=x)%=mod) if(y&1) (res*=x)%=mod;
return res;
}
int ck(int x,int y,int z){
int res=0;
for(int i=0;i<3;i++){
int fg1=((x>>i)&1),fg2=((y>>i)&1),fg3=((z>>i)&1);
if(fg1!=fg2){
res+=(fg1<<i);
}
else{
res+=(fg3<<i);
}
}
return res;
}
int dfs(int x,int y,int z){
memset(dp,0,sizeof dp);
dp[0][0]=1;
for(int i=0;i<32;i++){
int fg1=((x>>i)&1),fg2=((y>>i)&1),fg3=((z>>i)&1);
int now=fg1*4+fg2*2+fg3;
for(auto t:way){
for(int j=0;j<8;j++){
(dp[i+1][ck(t,now,j)]+=dp[i][j])%=mod;
}
}
}
return dp[32][0];
}
inline void solve(){
cin>>l1>>r1>>l2>>r2>>l3>>r3;
int ans1=dfs(r1,r2,r3),
ans2=dfs(r1,r2,l3-1),
ans3=dfs(r1,l2-1,r3),
ans4=dfs(r1,l2-1,l3-1),
ans5=dfs(l1-1,r2,r3),
ans6=dfs(l1-1,r2,l3-1),
ans7=dfs(l1-1,l2-1,r3),
ans8=dfs(l1-1,l2-1,l3-1);
int fenzi=((ans1-ans2-ans3+ans4-ans5+ans6+ans7-ans8)%mod+mod)%mod;
int fenmu=(r1-l1+1)*(r2-l2+1)%mod*(r3-l3+1)%mod;
cout<<(mod+1-fenzi*qpow(fenmu,mod-2)%mod)%mod;
}
signed main(){
ios_base::sync_with_stdio(false), cin.tie(0);
cout << fixed << setprecision(12);
int t = 1; // cin >> t;
while(t--) solve();
return 0;
}
C. Cutting with Lasers
队友单切,他说是模拟扫描线加一点讨论即可。
#include <bits/stdc++.h>
#pragma gcc optimize("O2")
#pragma g++ optimize("O2")
#define int long long
#define endl '\n'
using namespace std;
const int N = 1e6 + 10, MOD = 1e9 + 7;
struct point { int x, y; } p[N];
struct line { point st, ed; } l[N];
int col[1010][1010], row[1010][1010];
bool check (int x, int y){
return (1 <= x) && (1000 >= x) && (1 <= y) && (1000 >= y);
}
bool vis[1010][1010];
int cal[N];
int getpos(int x, int y) { return x * 1001 + y; }
int find(int x, int y){
if(vis[x][y]) return 0;
vis[x][y] = 1, cal[1] = x * 1001 + y;;
int cnt = 1;
for(int st = 1, ed = 2; st < ed; st++){
int nx = cal[st] / 1001, ny = cal[st] % 1001;
if(check(nx, ny + 1) && !row[nx][ny] && !vis[nx][ny + 1]){
vis[nx][ny + 1] = 1, cal[ed++] = getpos(nx, ny + 1), ++cnt;
}
if(check(nx, ny - 1) && !row[nx][ny - 1] && !vis[nx][ny - 1]){
vis[nx][ny - 1] = 1, cal[ed++] = getpos(nx, ny - 1), ++cnt;
}
if(check(nx + 1, ny) && !col[nx][ny] && !vis[nx + 1][ny]){
vis[nx + 1][ny] = 1, cal[ed++] = getpos(nx + 1, ny), ++cnt;
}
if(check(nx - 1, ny) && !col[nx - 1][ny] && !vis[nx - 1][ny]){
vis[nx - 1][ny] = 1, cal[ed++] = getpos(nx - 1, ny), ++cnt;
}
}
return cnt;
}
inline void solve(){
int n = 0; cin >> n;
for(int i = 1; i <= n + 1; i++) cin >> p[i].x >> p[i].y;
int lastx = 0, lasty = 0;
for(int i = 1; i <= n; i++){
if(p[i].x == p[i + 1].x){
int st = min(p[i].y, p[i + 1].y) + 1, ed = max(p[i].y, p[i + 1].y);
for(int j = st; j <= ed; j++) col[p[i].x][j] = 1;
} else {
int st = min(p[i].x, p[i + 1].x) + 1, ed = max(p[i].x, p[i + 1].x);
for(int j = st; j <= ed; j++) row[j][p[i].y] = 1;
}
}
int ans = 0;
find(1, 1);
for(int i = 1; i <= 1000; i++){
for(int j = 1; j <= 1000; j++) ans = max(ans, find(i, j));
}
cout << ans << endl;
}
signed main(){
ios_base::sync_with_stdio(false), cin.tie(0);
cout << fixed << setprecision(12);
int t = 1; // cin >> t;
while(t--) solve();
return 0;
}
D. Displacing Particles
签到题,考虑检测过程就是对行列一起二分,考虑两个数输出被二分次数更多的次数即可。
#include <bits/stdc++.h>
#pragma gcc optimize("O2")
#pragma g++ optimize("O2")
#define int long long
#define endl '\n'
using namespace std;
const int N = 2e5 + 10, MOD = 1e9 + 7;
inline void solve(){
int n,x,y;
cin>>n>>x>>y;
int cnt=0;
for(;x%2==0&&y%2==0;cnt++,x/=2,y/=2);
cout<<n-cnt-1;
}
signed main(){
ios_base::sync_with_stdio(false), cin.tie(0);
cout << fixed << setprecision(12);
int t = 1; // cin >> t;
while(t--) solve();
return 0;
}
E. Eliminating Ballons
签到,贪心。
考虑一个高度为
h
i
h_i
hi 的气球,如果前面有一个没被消耗掉的高度为
h
i
−
1
h_i -1
hi−1的气球那就对答案次数没有影响。
注意数组大小。
#include <bits/stdc++.h>
#pragma gcc optimize("O2")
#pragma g++ optimize("O2")
#define int long long
#define endl '\n'
using namespace std;
const int N = 1e6 + 10, MOD = 1e9 + 7;
int a[N], b[N];
inline void solve(){
int n = 0; cin >> n;
for(int i = 1; i <= n; i++) cin >> a[i];
for(int i = 1; i <= n; i++){
if(b[a[i] + 1]) b[a[i] + 1] -= 1;
b[a[i]] += 1;
}
int ans = 0;
for(int i = 1; i <= 1e6; i++) ans += b[i];
cout << ans << endl;
}
signed main(){
ios_base::sync_with_stdio(false), cin.tie(0);
cout << fixed << setprecision(12);
int t = 1; // cin >> t;
while(t--) solve();
return 0;
}
F. Multidimensional Hangman
每个n个长度为c的匹配串,每个串中间有个通配符,求能匹配上最多匹配串的字典序最小字符串和其匹配数量。
每次把一个匹配串对应的所有可能字符串insert到map里,然后遍历map即可。
#include <bits/stdc++.h>
#pragma gcc optimize("O2")
#pragma g++ optimize("O2")
#define int long long
#define endl '\n'
using namespace std;
const int N = 1e6 + 10, MOD = 1e9 + 7;
map<string,int>mp;
inline void solve(){
int n, c; cin >> n >> c;
for(int i = 1; i <= n; i++){
string s; cin >> s;
int pos = 0;
for(int j = 0; j < s.length(); j++) if(s[j] == '*') pos = j;
for(int j = 0; j < 26; j++){
s[pos] = (char)(j + 'a');
mp[s]++;
}
}
int ans=0;
string anss="";
for(auto [x,y]:mp){
if(y>ans){
anss=x;ans=y;
}
}
cout<<anss<<" "<<ans;
}
signed main(){
ios_base::sync_with_stdio(false), cin.tie(0);
cout << fixed << setprecision(12);
int t = 1; // cin >> t;
while(t--) solve();
return 0;
}
G. Geometry of Triangles
有若干个通过对称反转形成的三角形,要求保留部分三角形且轮廓不变,求最小面积。(保证三角形互不重叠)
容易发现将所有共边的三角形连边,形成的是一个树结构,考虑一个形如”没有上司的舞会“的树dp即可。
(vp后5min写出来sad喵)
#include <bits/stdc++.h>
#pragma gcc optimize("O2")
#pragma g++ optimize("O2")
#define int long long
#define endl '\n'
#define double long double
using namespace std;
const int N = 2e5 + 10, mod = 1e9 + 7;
int n,cnt;
struct point{
int x,y;
bool operator<(const point &t)const {
return x<t.x||x==t.x&&y<t.y;
}
bool operator==(const point &t)const {
return x==t.x&&y==t.y;
}
};
struct node{
point a,b;
double dis(){
return sqrtl(1.0 * (a.x - b.x) * (a.x - b.x) + 1.0 * (a.y - b.y) * (a.y - b.y));
}
bool operator<(const node &t)const {
return a<t.a||a==t.a&&b<t.b;
}
};
point minn(point x,point y){
if(x.x<y.x||x.x==y.x&&x.y<y.y)return x;
return y;
}
point maxx(point x,point y){
if(x.x>y.x||x.x==y.x&&x.y>y.y)return x;
return y;
}
map<node,int>mp;
vector<int>p[200005];
const double inf =1e18;
double ww[N];
double dp[N][2];
void dfs(int u,int fa){
for(auto v:p[u]){
if(v==fa)continue;
dfs(v,u);
}
dp[u][1]=ww[u];
for(auto v:p[u]){
if(v==fa)continue;
dp[u][1]+=min(dp[v][0],dp[v][1]);
}
if(p[u].size()<=2){
dp[u][0]=inf;
}
else{
for(auto v:p[u]){
if(v==fa)continue;
dp[u][0]+=dp[v][1];
}
}
}
inline void solve(){
cin>>n;
for(int i=1;i<=n;i++){
point q,w,e;
cin>>q.x >> q.y >> w.x >> w.y >> e.x >> e.y;
node edge1={minn(q, w), maxx(q, w)};
node edge2={minn(e, w), maxx(e, w)};
node edge3={minn(e, q), maxx(q, e)};
if(mp.count(edge1)){
p[mp[edge1]].emplace_back(i);
p[i].emplace_back(mp[edge1]);
}
if(mp.count(edge2)){
p[mp[edge2]].emplace_back(i);
p[i].emplace_back(mp[edge2]);
}
if(mp.count(edge3)){
p[mp[edge3]].emplace_back(i);
p[i].emplace_back(mp[edge3]);
}
double d1=edge1.dis(),d2=edge2.dis(),d3=edge3.dis();
double d4=(d1+d2+d3)/2;
ww[i]=sqrtl(d4*(d4-d1)*(d4-d2)*(d4-d3));
mp[edge1] = i;
mp[edge2] = i;
mp[edge3] = i;
}
dfs(1,0);
cout<<min(dp[1][0],dp[1][1]);
}
signed main(){
ios_base::sync_with_stdio(false), cin.tie(0);
cout << fixed << setprecision(1);
int t = 1; // cin >> t;
while(t--) solve();
return 0;
}
H. Helping the Transit
强连通分量裸题。
缩完点输出没有出度和没有入度的点数量的max即可。
#include <bits/stdc++.h>
#pragma gcc optimize("O2")
#pragma g++ optimize("O2")
#define int long long
#define endl '\n'
using namespace std;
const int N = 2e5 + 10, MOD = 1e9 + 7;
int n, m;
int newid[N];
vector<int> p[N];
vector<vector<int>> scc;
int dfn[N], low[N], ins[N], idx, cnt;
vector<int> st, f;
void scc_tarjan(int u){
low[u] = dfn[u] = ++idx;
st.emplace_back(u);
ins[u] = 1;
for(auto v : p[u]){
if(!dfn[v]) scc_tarjan(v);
if(ins[v]) low[u] = min(low[u], low[v]);
}
if(low[u] == dfn[u]){
++cnt;
f.clear();
while(1){
int v = st.back(); st.pop_back();
f.emplace_back(v);
ins[v] = 0;
newid[v] = cnt;
if(u == v) break;
}
scc.emplace_back(f);
}
}
vector<int>g[500005];
int ind[500005],outd[500005];
inline void solve(){
cin >> n >> m;
for(int i = 1; i <= m; i++){
int u, v; cin >> u >> v;
p[u].emplace_back(v);
}
for(int i = 1; i <= n; i++){
if(dfn[i]) continue;
scc_tarjan(i);
}
if(cnt==1){
cout<<0<<endl;
return;
}
for(int i=1;i<=n;i++){
for(auto v:p[i]){
if(newid[i]!=newid[v]){
ind[newid[v]]++;
outd[newid[i]]++;
}
}
}
int cnt1=0,cnt2=0;
for(int i=1;i<=cnt;i++){
if(ind[i]==0)cnt1++;
if(outd[i]==0)cnt2++;
}
cout<<max(cnt1,cnt2);
}
signed main(){
ios_base::sync_with_stdio(false), cin.tie(0);
cout << fixed << setprecision(12);
int t = 1; //cin >> t;
while(t--) solve();
return 0;
}
I. Intercepting Information
签到 ,队友单切
#include <bits/stdc++.h>
#pragma gcc optimize("O2")
#pragma g++ optimize("O2")
#define int long long
#define endl '\n'
using namespace std;
const int N = 2e5 + 10, MOD = 1e9 + 7;
inline void solve(){
for(int i = 1; i <= 9; i++){
int x; cin >> x;
if(x == 9){ cout << 'F'; return; }
}
cout << 'S' << endl;
}
signed main(){
ios_base::sync_with_stdio(false), cin.tie(0);
cout << fixed << setprecision(12);
int t = 1; // cin >> t;
while(t--) solve();
return 0;
}
J. Playing 23
队友写的,模拟一个23点的游戏,坑点有点多。
一个是输入的时候加分要和10取min
一个是每张牌至多四张。
#include <bits/stdc++.h>
#pragma gcc optimize("O2")
#pragma g++ optimize("O2")
#define int long long
#define endl '\n'
using namespace std;
const int N = 1e6 + 10, MOD = 1e9 + 7;
int a[N], b[N];
int mp[N];
inline void solve(){
int n = 0; cin >> n;
int cnt1 = 0, cnt2 = 0;
int x;
for(int i = 1; i <= 2; i++) cin >> x, mp[x]++, cnt1 += min(x,10ll);
for(int i = 1; i <= 2; i++) cin >> x, mp[x]++, cnt2 += min(x,10ll);
for(int i = 1; i <= n; i++){
int x = 0; cin >> x, mp[x]++;
cnt1 += min(x,10ll), cnt2 += min(x,10ll);
}
int r=23-cnt2, l=23-cnt1, ans=1e9;
if(mp[r]<4) ans=r;
if(l<r)
{
for(int i=l+1;i<=r;i++)
{
if(mp[i]<4) ans=min(ans,i);
}
}
if(ans<=10)
{
cout<<ans<<"\n";
}
else cout<<"-1\n";
}
signed main(){
ios_base::sync_with_stdio(false), cin.tie(0);
cout << fixed << setprecision(12);
int t = 1; // cin >> t;
while(t--) solve();
return 0;
}
K. Kalel, the Jumping Frog
vp的时候想到了矩阵快速幂,没想到怎么压第三维。赛后问别人才知道,矩阵每点维护一个多项式即可。这题就是三个板子拼起来,裸的矩阵加速递推+矩阵快速幂+朴素多项式乘法。复杂度是 O ( d 3 k 2 l o g n ) O(d^3k^2logn) O(d3k2logn) 计算一下大约是1e9,但是开了15秒时间非常充裕。
#include <bits/stdc++.h>
#define int long long
//#define endl '\n'
#define lowbit(x) (x&(-x))
#define ull unsigned long long
#define pii pair<int,int>
using namespace std;
const string yes="Yes\n",no="No\n";
const int N = 100005,inf = 1e18,mod=1000000007,M=1e9;
int qpow(int x,int y=mod-2,int mo=mod,int res=1){
for(;y;(x*=x)%=mo,y>>=1)if(y&1)(res*=x)%=mo;
return res;
}
struct poly{
int a[401];
void init(){memset(a,0,sizeof(a));}
poly operator * (const poly &t) const{
poly ans;ans.init();
for(int i=0;i<=400;i++){
for(int j=0;j<=i;j++){
(ans.a[i]+=a[j]*t.a[i-j])%=M;
}
}
return ans;
}
void operator += (const poly &t){
for(int i=0;i<=400;i++){
(a[i]+=t.a[i])%=M;
}
}
};
struct mat{
poly a[10][10];
void init(){memset(a,0,sizeof(a));}
void init1(){
memset(a,0,sizeof(a));
for(int i=0;i<10;i++){
a[i][i].a[0]=1;
}
}
mat operator * (const mat &t)const{
mat ans;ans.init();
for(int i=0;i<10;i++){
for(int j=0;j<10;j++){
for(int k=0;k<10;k++){
ans.a[i][j]+=(a[i][k]*t.a[k][j]);
}
}
}
return ans;
}
}ans,base;
mat qpow(mat x,int y){
mat res;res.init1();
for(;y;y>>=1,x=x*x)if(y&1)res=res*x;
return res;
}
int n,m,k;
void solve(){
cin>>n>>m>>k;
for(int i=1;i<=m;i++){
int d,p;cin>>d>>p;
d--;base.a[0][d].a[p]++;
}
for(int i=1;i<10;i++){
base.a[i][i-1].a[0]=1;
}
ans.a[0][0].a[0]=1;
ans=qpow(base,n-1)*ans;
int sum=0;
for(int i=0;i<=k;i++){
(sum+=ans.a[0][0].a[i])%=M;
}
cout<<sum;
}
signed main(){
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
cout<<fixed<<setprecision(12);
int t=1;
while (t--)
solve();
}
L. Listing Tedious Paths
裸虚树dp 详细题解可以在知乎搜ygg。(还有树上启发式合并写法)
#include <bits/stdc++.h>
using namespace std;
vector<int>p[500005];
int dfn[500005],sz[500005],pr[500005],dep[500005],fa[500005];
int lst[500005];
int cnt,n;
void dfs1(int u){
if(fa[u]!=0) p[u].erase(find(p[u].begin(),p[u].end(),fa[u]));
sz[u]=1;
for(auto v:p[u]){
if(v==fa[u])continue;
fa[v]=u;dep[v]=dep[u]+1;
dfs1(v);
sz[u]+=sz[v];
}
sort(p[u].begin(),p[u].end(),[](const int x,const int y){return sz[x]>sz[y];});
}
void dfs2(int u){
dfn[u]=++cnt;
for(auto v:p[u]){
if(v==p[u][0]){pr[v]=pr[u];}
else{pr[v]=v;}
dfs2(v);
}
lst[u]=cnt;
}
int lca(int u,int v){
while(pr[u]!=pr[v]){
if(dep[pr[u]]>dep[pr[v]]){u=fa[pr[u]];}
else{v=fa[pr[v]];}
}
return dep[u]<dep[v]?u:v;
}
vector<int>col[100005],now[100005],newtree[100005];
vector<int>st;
int c[100005],sum[100005],colcnt[100005],dpsz[100005];
int uu[100005],vv[100005];
void dfs3(int u){
for(auto v:p[u]){
dfs3(v);
sum[u]+=sum[v];
}
}
void dfs_dp(int u,int f,int color,int sumcol){
if(c[u]==color)dpsz[u]=1;
for(auto v:newtree[u]){
dfs_dp(v,u,color,sumcol);
dpsz[u]+=dpsz[v];
}
sum[u]+=dpsz[u]*(sumcol-dpsz[u]);
sum[f]-=dpsz[u]*(sumcol-dpsz[u]);
}
void get(int color){
sort(col[color].begin(),col[color].end(),[](const int x,const int y){return dfn[x]<dfn[y];});
st.push_back(1);now[color].push_back(1);
for(auto u:col[color]){//建立虚树
if(u==1)continue;
int LCA=lca(st.back(),u);
while(st.size()>1&&dfn[st.back()]>dfn[LCA]){
int v=st.back();st.pop_back();now[color].push_back(v);
if(dfn[st.back()]>dfn[LCA]){
newtree[st.back()].push_back(v);
}
else{
newtree[LCA].push_back(v);
}
}
if(LCA!=st.back())st.push_back(LCA);
st.push_back(u);
}
while(st.size()>1){
int u=st.back();st.pop_back();now[color].push_back(u);
newtree[st.back()].push_back(u);
}
st.clear();
//虚树上dp
dfs_dp(1,0,color,col[color].size());
for(auto x:now[color]){//清空
dpsz[x]=0;
newtree[x].clear();
}
}
void solve(){
cin>>n;
for(int i=1;i<=n;i++){
cin>>c[i];
colcnt[c[i]]++;
col[c[i]].push_back(i);
}
for(int i=1;i<n;i++){
int u,v;cin>>u>>v;
p[u].push_back(v);
p[v].push_back(u);
uu[i]=u;vv[i]=v;
}
dfs1(1);
dfs2(1);
for(int i=1;i<=n;i++){
if(col[i].size())get(i);
}
dfs3(1);
for(int i=1;i<n;i++){
if(fa[uu[i]]==vv[i]){
cout<<sum[uu[i]]<<" ";
}
else{
cout<<sum[vv[i]]<<" ";
}
}
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
int t=1;
//cin>>t;
while(t--){
solve();
}
}
N. Numbers on both Sides
两倍长,区间前k大和,主席树板子。
#include <bits/stdc++.h>
#pragma gcc optimize("O2")
#pragma g++ optimize("O2")
#define int long long
#define endl '\n'
using namespace std;
const int N = 2e5 + 10, MOD = 1e9 + 7;
int a[N],b[N];
namespace PDT{
#define ls lc[rt]
#define rs rc[rt]
int tree[N << 5], lc[N << 5], rc[N << 5], root[N], tot, sum[N<<5];
void update(int &rt, int pre, int l, int r, int pos){
rt = ++tot, lc[rt] = lc[pre], rc[rt] = rc[pre], tree[rt] = tree[pre] + 1, sum[rt] = sum[pre] + pos;
if(l == r) return;
int mid = l + r >> 1;
if(mid >= pos) update(lc[rt], lc[pre], l, mid, pos);
else update(rc[rt], rc[pre], mid + 1, r, pos);
}
int query(int l, int r, int L, int R, int k){
if(l == r) return l * k;
int mid = l + r >> 1, res = tree[rc[R]] - tree[rc[L]];
if(res >= k) return query(mid+1, r, rc[L], rc[R], k);
else return sum[rc[R]]-sum[rc[L]]+query(l, mid, lc[L], lc[R], k - res);
}
}
using PDT::update;
using PDT::query;
using PDT::root;
int pre[N],ans,k,l;
inline void solve(){
int n = 0; cin >> n;
for(int i = 1; i <= n; i++) {cin >> a[i];a[i+n]=a[i];}
for(int i = 1; i <= n; i++) {cin >> b[i];b[i+n]=b[i];}
for(int i = 1; i <= 2*n; i++) update(root[i], root[i - 1], 1, 1e9, b[i]);
for(int i=1;i<=2*n;i++){
pre[i]=pre[i-1]+a[i];
}
cin>>k>>l;
for(int i=n-k+1;i<=n+1;i++){
ans=max(ans,pre[i+k-1]-pre[i-1]+query(1,1e9,root[i-1],root[i+k-1],l));
}
cout<<ans;
}
signed main(){
ios_base::sync_with_stdio(false), cin.tie(0);
cout << fixed << setprecision(12);
int t = 1; //cin >> t;
while(t--) solve();
return 0;
}