#include #include #include #include using namespace std; typedef long long llong; typedef long double ldouble; int n,m; int s[200111]; int p[200111]; int c[200111]; vector d[200111]; vector hatedBy[200111]; llong INF = 2000000000000000000LL; struct line { llong a,b; }; ldouble Intersection(line A,line B) { return (ldouble)(B.b - A.b) / (ldouble)(A.a - B.a); } llong Eval(line A,llong x) { return A.a * x + A.b; } llong MIN(llong a,llong b) { if (a < b) return a; else return b; } struct hull { vector s; void addLine(line newL) ///With the smallest slope so far, no duplicates { int len; while(s.size() > 1) { len = s.size(); if (Intersection(s[len-2], s[len-1]) >= Intersection(s[len-2], newL)) s.pop_back(); else break; } s.push_back(newL); } llong query(llong x) { if (s.empty()) return INF; int l = 0; int r = (int)s.size() - 2; llong best; int mid; best = Eval(s.back(), x); while(l <= r) { mid = (l+r) / 2; best = MIN(best, Eval(s[mid], x)); if (Intersection(s[mid], s[mid+1]) < (ldouble)x) l = mid + 1; else r = mid - 1; } return best; } }; hull IT[800111]; int LEAFOFFSET = 1; int order[200111]; bool SO(int a,int b) { return s[a] < s[b]; } void recAddLines(int ver,int L,int R,int l,int r,line myLine) { if (L > r || R < l) return; else if (L >= l && R <= r) { IT[ver].addLine(myLine); return; } else { recAddLines(2*ver, L, (L+R)/2, l, r, myLine); recAddLines(2*ver+1, (L+R)/2 + 1, R, l, r, myLine); } } void addLines(int L,int R,line myLine) { recAddLines(1,1,LEAFOFFSET+1,L,R,myLine); } llong summarise(int ind,llong x) { llong val = INF; ind += LEAFOFFSET; while(ind > 0) { val = MIN(val, IT[ind].query(x)); ind /= 2; } return val; } int main() { //freopen("test.txt","r",stdin); int i,j; int L,hate; int lastInd; line curLine; int C; scanf("%d %d",&n,&m); LEAFOFFSET = 1; while(LEAFOFFSET < m) LEAFOFFSET *= 2; LEAFOFFSET--; for (i=1;i<=n;i++) { scanf("%d %d",&s[i],&p[i]); order[i] = i; } for (i=1;i<=m;i++) { scanf("%d %d",&c[i],&L); for (j=1;j<=L;j++) { scanf("%d",&hate); d[i].push_back(hate); hatedBy[hate].push_back(i); } } sort(order+1,order+1+n,SO); for (i=1;i<=n;i++) { C = order[i]; curLine.a = -2LL * (llong)s[C]; curLine.b = (llong)s[C] * (llong)s[C] + (llong)p[C]; lastInd = 1; for (j=0;j lastInd) { addLines(lastInd, hatedBy[C][j]-1, curLine); } lastInd = hatedBy[C][j] + 1; } if (lastInd <= m) addLines(lastInd, m, curLine); } for (i=1;i<=m;i++) { printf("%lld\n",summarise(i, c[i]) + (llong)c[i] * (llong)c[i]); } return 0; }