The third problem is convex title:. Http://45.32.26.14/problem/887
The area can be a "point i to point i + 1 of the cross product" and a section (and prefix), plus the start and end points of the cross product is obtained.
So he n- 2 a.
#include<cstdio> #include<cstring> #include<algorithm> #define ll long long #define db double using namespace std; int rdn() { int ret=0;bool fx=1;char ch=getchar(); while(ch>'9'||ch<'0'){if(ch=='-')fx=0;ch=getchar();} while(ch>='0'&&ch<='9')ret=ret*10+ch-'0',ch=getchar(); return fx?ret:-ret; } const int N=2e6+5,mod=1e9+7; int upt(int x){while(x>=mod)x-=mod;while(x<0)x+=mod;return x;} int pw(int x,int k) {int ret=1;while(k){if(k&1)ret=(ll)ret*x%mod;x=(ll)x*x%mod;k>>=1;}return ret;} int n,s[N],ans; struct Node{ int x,y;}a[N]; int cro2(Node u,Node v){return upt((ll)u.x*v.y%mod-(ll)v.x*u.y%mod);} int cal(int l,int r) { if(l<r)return upt(s[r-1]-s[l-1]); return upt(s[r-1]+s[n]-s[l-1]); } namespace D{ db s[N]; db cro2(Node u,Node v){return (db)u.x*v.y-(db)v.x*u.y;} db cal(int l,int r) { if(l<r)return s[r-1]-s[l-1]; return s[r-1]+s[n]-s[l-1]; } } int Id(int x) { if(!x)x=n; if(x>n)x-=n; return x;} int main() { n=rdn(); for(int i=n;i;i--) a[i].x=rdn(), a[i].y=rdn(); a[n+1]=a[1]; for(int i=1;i<=n;i++) { s[i]=upt(s[i-1]+cro2(a[i],a[i+1])); D::s[i]=D::s[i-1]+D::cro2(a[i],a[i+1]); } for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { if(j==i||j==Id(i-1)||j==Id(i+1))continue; int x=upt(cal(i,j)+cro2(a[j],a[i])); int y=upt(cal(j,i)+cro2(a[i],a[j])); db x2=D::cal(i,j)+D::cro2(a[j],a[i]); db y2=D::cal(j,i)+D::cro2(a[i],a[j]); if(x2>y2)ans=upt(ans+x-y); else ans=upt(ans+y-x); } } printf("%lld\n",(ll)ans*pw(2,mod-2)%mod); return 0; }
I did not expect the cross product of the formula you can also use prefixes and optimization! ! ! Careful analysis ......
So then seek just the prefix and prefix and can be. Like hash the same.
Double pointer can locate each point corresponding to point i j, satisfying convex hull area i ~ j is equal to the total area of less than half, i ~ (j + 1) is larger than the area of the convex hull of half of the total area. Operators can then some.
Note that the chain ring off the array to become twice.
#include<cstdio> #include<cstring> #include<algorithm> #define ll long long #define db double using namespace std; int rdn() { int ret=0;bool fx=1;char ch=getchar(); while(ch>'9'||ch<'0'){if(ch=='-')fx=0;ch=getchar();} while(ch>='0'&&ch<='9')ret=ret*10+ch-'0',ch=getchar(); return fx?ret:-ret; } const int N=2e6+5,M=N<<1,mod=1e9+7; int upt(int x){while(x>=mod)x-=mod;while(x<0)x+=mod;return x;} int n,vl[M],s1[M],s2[M],sx[M],sy[M],All; db s[M],dAll; struct Node{ int x,y;}a[M];//a[M] not a[N]!!! db cro2d(Node u,Node v){return (db)u.x*v.y-(db)v.x*u.y;} int cro2(Node u,Node v){return upt((ll)u.x*v.y%mod-(ll)v.x*u.y%mod);} bool chk(int i,int j)//(i,j)<=!(i,j) { db ta=s[j-1]-s[i-1]+cro2d(a[j],a[i]); return ta<dAll-ta; } int cal(int i,int j) { int tp=upt(s2[j-1]-s2[i-1]-vl[i]); tp=upt(tp-(ll)(j-i)*s1[i-1]%mod); int tx=upt(sx[j]-sx[i+1]),ty=upt(sy[j]-sy[i+1]); tp=(tp+(ll)tx*a[i].y)%mod; tp=upt(tp-(ll)ty*a[i].x%mod); return tp; } int main() { n=rdn(); for(int i=n;i;i--) { a[i].x=rdn(); a[i].y=rdn(); a[i+n]=a[i]; } for(int i=1,lm=n*2;i<lm;i++) { vl[i]=cro2(a[i],a[i+1]); s1[i]=upt(s1[i-1]+vl[i]); s2[i]=upt(s2[i-1]+s1[i]); sx[i]=upt(sx[i-1]+a[i].x); sy[i]=upt(sy[i-1]+a[i].y); s[i]=s[i-1]+cro2d(a[i],a[i+1]); } All=s1[n]; dAll=s[n]; int j=1,ans=0; for(int i=1;i<=n;i++) { while(chk(i,j+1))j++; ans=(ans+(ll)(j-i-1)*All)%mod; ans=upt(ans-2*cal(i,j)); } printf("%d\n",ans); return 0; }