如果现在能得到[1,t]范围内的任意值。若新来了一个数x,x<=t+1,则可以得到新的范围[1,t+x]。
利用这个性质,O(T*(N+M))时间处理下就行了。
(膜zhenhao大佬)
#include <bits/stdc++.h>
using namespace std;
void read(int&a){
char ch;while(!((ch=getchar())>='0')&&(ch<='9'));
a=ch-'0';while(((ch=getchar())>='0')&&(ch<='9'))a*=10,a+=ch-'0';
}
inline void prin_d(long long x)
{
if (x > 9)
{
prin_d(x / 10);
}
putchar(x % 10 + '0');
return ;
}
const int MAXN=1010;
int a[MAXN][MAXN],stk[MAXN];
int main()
{
int n,i,j,x,y,xi,yi,T,k,stksum;
long long ans;
while(~scanf("%d",&n))
{
for(i=1;i<=n;i++)
{
read(a[i][0]);
for(j=1;j<=a[i][0];j++)
read(a[i][j]);
sort(a[i]+1,a[i]+a[i][0]+1);
}
read(T);
while(T--)
{
read(x);read(y);read(k);
ans=0;
xi=yi=1;
while(xi<=a[x][0]&&a[x][xi]<=ans+1)
{
ans+=a[x][xi];
xi++;
}
stksum=0;
for(i=0;i<min(k,a[y][0]);i++)
{
while(yi<=a[y][0]&&a[y][yi]<=ans+1)
{
stk[stksum++]=a[y][yi];
yi++;
}
if(stksum)
{
ans+=stk[stksum-1];
stksum--;
}
else
break;
while(xi<=a[x][0]&&a[x][xi]<=ans+1)
{
ans+=a[x][xi];
xi++;
}
}
prin_d(ans);
puts("");
}
}
}