分治
类似ZJOI2016的最短路分治思想
妈的有毒
极大值有毒
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<queue>
#include<algorithm>
#include<stack>
#include<vector>
using namespace std;
char c;
inline void read(int&a){a=0;do c=getchar();while(c<'0'||c>'9');while(c<='9'&&c>='0')a=(a<<3)+(a<<1)+c-'0',c=getchar();}
struct Query
{
int l,r,C,sum,no;
bool ans;
}Q[200001];
inline bool cmp(Query a,Query b){return a.no<b.no;}
inline int Min(int&a,int b){return a>b?a=b:a;}
int w[200001],d[200001];
int G[20001][101],F[20001][101];
const
int INF=1<<30;
void Solve(int l,int r,int L,int R,bool lp)
{
if(l==r)
{
for(int i=L;i<=R;i++)
Q[i].ans=(Q[i].sum==w[l]&&d[l]<=Q[i].C);
int *A=lp?F[l]:G[l];
for(int i=1;i<=100;i++)
A[i]=INF;
A[w[l]]=d[l];
return;
}
int Mid=l+r>>1;
static Query Ca[200001];
int cnt=0,cnt2,cnt3;
for(int i=L;i<=R;i++)
if(Q[i].r<=Mid)
Ca[++cnt]=Q[i];
cnt2=cnt;
for(int i=L;i<=R;i++)
if(Q[i].l>Mid)
Ca[++cnt2]=Q[i];
cnt3=cnt2;
for(int i=L;i<=R;i++)
if(Q[i].l<=Mid&&Q[i].r>Mid)
Ca[++cnt3]=Q[i];
for(int i=L;i<=R;i++)
Q[i]=Ca[i-L+1];
Solve(l,Mid,L,L+cnt-1,1);
Solve(Mid+1,r,L+cnt,L+cnt2-1,0);
for(int i=L+cnt2;i<=R;i++)
{
int Mi=INF;
for(int j=0;j<=Q[i].sum;j++)
Min(Mi,max(F[Q[i].l][j],G[Q[i].r][Q[i].sum-j]));
Q[i].ans=Mi<=Q[i].C;
}
if(!lp)
{
for(int j=1;j<=100;j++)
G[l][j]=INF;
G[l][w[l]]=d[l];
for(int i=l+1;i<=r;i++)
{
for(int j=1;j<=100;j++)
{
G[i][j]=G[i-1][j];
if(j>=w[i])
Min(G[i][j],max(G[i-1][j-w[i]],d[i]));
}
}
}
else
{
for(int j=1;j<=100;j++)
F[r][j]=INF;
F[r][w[r]]=d[r];
for(int i=r-1;i>=l;i--)
{
for(int j=1;j<=100;j++)
{
F[i][j]=F[i+1][j];
if(j>=w[i])
Min(F[i][j],max(F[i+1][j-w[i]],d[i]));
}
}
}
}
int main()
{
int t;
read(t);
while(t--)
{
int n,m;
read(n),read(m);
for(int i=1;i<=n;i++)read(w[i]);
for(int i=1;i<=n;i++)read(d[i]);
for(int i=1;i<=m;i++)
read(Q[i].l),read(Q[i].r),read(Q[i].C),read(Q[i].sum),Q[i].no=i;
Solve(1,n,1,m,0);
sort(Q+1,Q+1+m,cmp);
for(int i=1;i<=m;i++)
putchar(Q[i].ans?'0':'1');
puts("");
}
return 0;
}