【NOI2015模拟1.17】⑨
2018-01-04 17:38
344 查看
Description
Cirno闲着无事的时候喜欢冰冻青蛙。Cirno每次从雾之湖中固定的n个结点中选出一些点构成一个简单多边形,Cirno运用自己的能力能将此多边形内所有青蛙冰冻。
雾之湖生活着m只青蛙,青蛙有大有小,所以每只青蛙的价值为一个不大于10000的正整数。
Cirno很想知道每次冻住的青蛙的价值总和。因为智商有限,Cirno将这个问题交给完美算术教室里的你。
因为爱护动物,所以每次冻结的青蛙会被放生。也就是说一只青蛙可以被多次统计。
-10000<=x,y<=10000; 0
Solution
计算几何式懵逼我们知道可以先选择一个原点,然后通过类似叉积的做法求出这个多边形的有向面积
这里的面积定义成内部的点的个数
于是我们只需要求出每个三角形内部的点的权值和,两次排序之后树状数组维护即可。
Code
#include <cmath> #include <cstdio> #include <cstring> #include <algorithm> #define fo(i,a,b) for(int i=a;i<=b;i++) #define fd(i,a,b) for(int i=a;i>=b;i--) using namespace std; typedef double db; typedef long long ll; const int N=1e3+5; int n,m,ans,Q,a ,ord ,S,Ans[N<<1][N<<1],tr[N<<1]; db eps=1e-7; void ins(int x,int y) {for(;x<=n+m;x+=x&-x) tr[x]+=y;} int query(int x) {int res=0;for(;x;x-=x&-x) res+=tr[x];return res;} int find(int l,int r) { if (l>r) swap(l,r); return query(r)-query(l-1); } struct P{ int x,y,v,id,w;db a; P(int _x=0,int _y=0) {x=_x;y=_y;v=id=w=a=0;} friend P operator + (P x,P y) {return P(x.x+y.x,x.y+y.y);} friend P operator - (P x,P y) {return P(x.x-y.x,x.y-y.y);} }p[N<<1],O,q[N<<1]; int cross(P x,P y) {return x.x*y.y-y.x*x.y;} int sig(int x) { if (x>0) return 1; if (x==0) return 0; if (x<0) return -1; } bool cmp(P x,P y) {return x.a<y.a;} db theta(P x,P y) { db a=x.x*y.x+x.y*y.y; a/=sqrt(x.x*x.x+x.y*x.y)*sqrt(y.x*y.x+y.y*y.y); return acos(a); } int main() { scanf("%d%d",&n,&m); fo(i,1,n) scanf("%d%d",&p[i].x,&p[i].y),p[i].id=i; fo(i,1,m) scanf("%d%d%d",&p[i+n].x,&p[i+n].y,&p[i+n].v); O=P(-20000,-20000); fo(i,1,n+m) p[i].a=atan2(p[i].y-O.y,p[i].x-O.x); sort(p+1,p+n+m+1,cmp); fo(i,1,n+m) { p[i].w=i; if (p[i].id) ord[p[i].id]=i; } fo(i,1,n+m) if (!p[i].v) { int tot=0; fo(j,i+1,n+m) { q[++tot]=p[j]; q[tot].a=theta(p[j]-O,p[i]-O)+theta(O-p[j],p[i]-p[j]); } sort(q+1,q+tot+1,cmp); fo(j,1,tot) if (q[j].v) ins(q[j].w,q[j].v); else Ans[i][q[j].w]=Ans[q[j].w][i]=find(q[j].w,p[i].w); fo(j,1,tot) if (q[j].v) ins(q[j].w,-q[j].v); } for(scanf("%d",&Q);Q;Q--) { scanf("%d",&S); int ans=0; fo(i,1,S) { scanf("%d",&a[i]);a[i]=ord[a[i]]; if (i!=1) ans+=sig(cross(p[a[i]]-O,p[a[i-1]]-O))*Ans[a[i]][a[i-1]]; } ans+=sig(cross(p[a[1]]-O,p[a[S]]-O))*Ans[a[1]][a[S]]; if (ans<0) ans=-ans; printf("%d\n",ans); } return 0; }
相关文章推荐
- JZOJ3975. 【NOI2015模拟1.17】串
- 【JZOJ 3976】【NOI2015模拟1.17】⑨
- JZOJ 3769. 【NOI2015模拟8.14】A+B
- JZOJ.3769【NOI2015模拟8.14】A+B
- 【JZOJ3973】【NOI2015模拟1.10】【NOI2013湖南省队集训】黑白树(wbtree)(并查集)
- 【JZOJ3773】【NOI2015模拟8.15】小 P 的烦恼
- 【jzoj3769】【NOI2015模拟8.14】【A+B】
- 【NOI2015模拟8.19】图(SPFA)
- 【NOI2015模拟8.20】编辑器 jzoj 3789 栈+神奇操作
- 【NOI2015模拟1.10】B组黑白树
- 【NOI2015模拟9.9】文理分科
- JZOJ3777. 【NOI2015模拟8.17】最短路(shortest)
- 3777. 【NOI2015模拟8.17】最短路(shortest)
- 【省选专题一】图论 jzoj 3821. 【NOI2015模拟9.9】文理分科 最小割
- 【NOI2015模拟8.14】A+B
- 【JZOJ3834】【NOI2015模拟9.14】【CF461D】Complicated Task(异或方程组+并查集)
- JZOJ 3786. 【NOI2015模拟8.19】图
- 【NOI2015模拟9.9】取石子(博弈)
- JZOJ3789. 【NOI2015模拟8.20】编辑器
- 【JZOJ3819】【NOI2015模拟9.9】【hdu 4111】取石子(博弈+贪心+记忆化搜索)