2391: Cirno的忧郁 - BZOJ
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分治
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 const 2 maxn=1010; 3 type 4 point=record 5 x,y,id,v:longint; 6 end; 7 aa=array[0..maxn*2]of longint; 8 var 9 a,b:array[0..maxn*2]of point; 10 s:array[0..maxn,0..maxn]of longint; 11 x,c:aa; 12 n,m,q:longint; 13 14 procedure swap(var x,y:longint); 15 var 16 t:longint; 17 begin 18 t:=x;x:=y;y:=t; 19 end; 20 21 procedure sort(l,r:longint;var a:aa); 22 var 23 i,j,y:longint; 24 begin 25 i:=l;j:=r;y:=a[(l+r)>>1]; 26 repeat 27 while a[i]<y do inc(i); 28 while a[j]>y do dec(j); 29 if i<=j then 30 begin 31 swap(a[i],a[j]); 32 inc(i);dec(j); 33 end; 34 until i>j; 35 if i<r then sort(i,r,a); 36 if j>l then sort(l,j,a); 37 end; 38 39 operator -(a,b:point)c:point; 40 begin 41 c.x:=a.x-b.x; 42 c.y:=a.y-b.y; 43 end; 44 45 operator *(a,b:point)c:longint; 46 begin 47 exit(a.x*b.y-a.y*b.x); 48 end; 49 50 procedure swap(var x,y:point); 51 var 52 t:point; 53 begin 54 t:=x;x:=y;y:=t; 55 end; 56 57 procedure sort(l,r:longint); 58 var 59 i,j:longint; 60 y:point; 61 begin 62 i:=l;j:=r;y:=a[(l+r)>>1]; 63 repeat 64 while (y-a[0])*(a[i]-a[0])<0 do inc(i); 65 while (y-a[0])*(a[j]-a[0])>0 do dec(j); 66 if i<=j then 67 begin 68 swap(a[i],a[j]); 69 inc(i);dec(j); 70 end; 71 until i>j; 72 if i<r then sort(i,r); 73 if j>l then sort(l,j); 74 end; 75 76 function find(k:longint):longint; 77 var 78 l,r,mid:longint; 79 begin 80 l:=1;r:=n+m; 81 while l<>r do 82 begin 83 mid:=(l+r)>>1; 84 if x[mid]<k then l:=mid+1 85 else r:=mid; 86 end; 87 exit(l); 88 end; 89 90 procedure add(x,y:longint); 91 begin 92 while x<=n+m do 93 begin 94 inc(c[x],y); 95 x:=x+(x and (-x)); 96 end; 97 end; 98 99 function sum(x:longint):longint; 100 begin 101 sum:=0; 102 while x>0 do 103 begin 104 inc(sum,c[x]); 105 x:=x-(x and (-x)); 106 end; 107 end; 108 109 procedure main; 110 var 111 i,j,cnt,ans:longint; 112 begin 113 read(n,m); 114 for i:=1 to n do 115 begin 116 read(a[i].x,a[i].y); 117 b[i]:=a[i]; 118 a[i].id:=i; 119 end; 120 for i:=n+1 to n+m do 121 read(a[i].x,a[i].y,a[i].v); 122 for i:=1 to n+m do 123 x[i]:=a[i].x; 124 sort(1,n+m,x); 125 for i:=1 to n do 126 begin 127 for j:=1 to n+m do 128 c[j]:=0; 129 a[0]:=b[i]; 130 cnt:=0; 131 for j:=1 to n+m do 132 if (a[j].x>=a[0].x) and ((a[j].x<>a[0].x) or (a[j].y<>a[0].y)) then 133 begin 134 inc(cnt); 135 swap(a[j],a[cnt]); 136 end; 137 sort(1,cnt); 138 for j:=1 to cnt do 139 begin 140 if a[j].id>0 then s[i,a[j].id]:=sum(find(a[j].x)-1) 141 else add(find(a[j].x),a[j].v); 142 end; 143 end; 144 for i:=1 to n do 145 for j:=1 to n do 146 if s[i,j]=0 then s[i,j]:=-s[j,i]; 147 read(q); 148 for i:=1 to q do 149 begin 150 read(cnt); 151 for j:=1 to cnt do 152 read(x[j]); 153 ans:=0; 154 for j:=1 to cnt do 155 inc(ans,s[x[j],x[j mod cnt+1]]); 156 writeln(abs(ans)); 157 end; 158 end; 159 160 begin 161 main; 162 end.