Description
 
Cirno闲着无事的时候喜欢冰冻青蛙。
Cirno每次从雾之湖中固定的n个结点中选出一些点构成一个简单多边形,Cirno运用自己的能力能将此多边形内所有青蛙冰冻。
雾之湖生活着m只青蛙,青蛙有大有小,所以每只青蛙的价值为一个不大于10000的正整数。
Cirno很想知道每次冻住的青蛙的价值总和。因为智商有限,Cirno将这个问题交给完美算术教室里的你。
因为爱护动物,所以每次冻结的青蛙会被放生。也就是说一只青蛙可以被多次统计。
 
Input
 
第一行2个正整数 n,m。
以下n行,每行2个整数xi,yi,表示第i个结点的坐标。
再以下m行,每行3个整数xj,yj,vj,表示第j个青蛙的坐标和价值。
第n+m+1行一个整数q,表示有q组询问。
每组询问有2行,第一行一个整数s(3<=s<=n),表示简单多边形的结点数。第二行s个正整数,顺时针或逆时针给出多边形的结点的编号(1--n)
 
Output
 
q行。
对于每个询问,每行输出一个整数表示冻结的青蛙的价值之和
 
Sample Input
4 3
2 2
3 5
7 4
5 1
3 4 2
4 3 7
6 3 90
2
3
1 2 3
4
1 4 3 2

Sample Output
9
99

HINT

数据范围】

对于30%的数据,n,m<=100; q<=100

对于60%的数据,n,m<=100; q<=10000

对于100%的数据,n,m<=1000; q<=10000

-10000<=x,y<=10000; 0<v<=10000

看见他三次了,还是写了吧

我们预处理出s[i,j]表示线段[i,j)下面的点权和

然后就可以像求多边形面积一样求权值和了

预处理这个很简单,枚举一个端点,然后极角排序,按顺序加点,用树状数组维护和加到点j的时候s[i,j]=sum(xi,xj-1),因为两个端点不能同时取要不然就多了,感觉有点像cdq分治

 const
maxn=;
type
point=record
x,y,id,v:longint;
end;
aa=array[..maxn*]of longint;
var
a,b:array[..maxn*]of point;
s:array[..maxn,..maxn]of longint;
x,c:aa;
n,m,q:longint; procedure swap(var x,y:longint);
var
t:longint;
begin
t:=x;x:=y;y:=t;
end; procedure sort(l,r:longint;var a:aa);
var
i,j,y:longint;
begin
i:=l;j:=r;y:=a[(l+r)>>];
repeat
while a[i]<y do inc(i);
while a[j]>y do dec(j);
if i<=j then
begin
swap(a[i],a[j]);
inc(i);dec(j);
end;
until i>j;
if i<r then sort(i,r,a);
if j>l then sort(l,j,a);
end; operator -(a,b:point)c:point;
begin
c.x:=a.x-b.x;
c.y:=a.y-b.y;
end; operator *(a,b:point)c:longint;
begin
exit(a.x*b.y-a.y*b.x);
end; procedure swap(var x,y:point);
var
t:point;
begin
t:=x;x:=y;y:=t;
end; procedure sort(l,r:longint);
var
i,j:longint;
y:point;
begin
i:=l;j:=r;y:=a[(l+r)>>];
repeat
while (y-a[])*(a[i]-a[])< do inc(i);
while (y-a[])*(a[j]-a[])> do dec(j);
if i<=j then
begin
swap(a[i],a[j]);
inc(i);dec(j);
end;
until i>j;
if i<r then sort(i,r);
if j>l then sort(l,j);
end; function find(k:longint):longint;
var
l,r,mid:longint;
begin
l:=;r:=n+m;
while l<>r do
begin
mid:=(l+r)>>;
if x[mid]<k then l:=mid+
else r:=mid;
end;
exit(l);
end; procedure add(x,y:longint);
begin
while x<=n+m do
begin
inc(c[x],y);
x:=x+(x and (-x));
end;
end; function sum(x:longint):longint;
begin
sum:=;
while x> do
begin
inc(sum,c[x]);
x:=x-(x and (-x));
end;
end; procedure main;
var
i,j,cnt,ans:longint;
begin
read(n,m);
for i:= to n do
begin
read(a[i].x,a[i].y);
b[i]:=a[i];
a[i].id:=i;
end;
for i:=n+ to n+m do
read(a[i].x,a[i].y,a[i].v);
for i:= to n+m do
x[i]:=a[i].x;
sort(,n+m,x);
for i:= to n do
begin
for j:= to n+m do
c[j]:=;
a[]:=b[i];
cnt:=;
for j:= to n+m do
if (a[j].x>=a[].x) and ((a[j].x<>a[].x) or (a[j].y<>a[].y)) then
begin
inc(cnt);
swap(a[j],a[cnt]);
end;
sort(,cnt);
for j:= to cnt do
begin
if a[j].id> then s[i,a[j].id]:=sum(find(a[j].x)-)
else add(find(a[j].x),a[j].v);
end;
end;
for i:= to n do
for j:= to n do
if s[i,j]= then s[i,j]:=-s[j,i];
read(q);
for i:= to q do
begin
read(cnt);
for j:= to cnt do
read(x[j]);
ans:=;
for j:= to cnt do
inc(ans,s[x[j],x[j mod cnt+]]);
writeln(abs(ans));
end;
end; begin
main;
end.
05-08 08:44