2019.6.12 simulation game - [thinking]

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;
}
Oops

  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;
}
View Code

 

Guess you like

Origin www.cnblogs.com/Narh/p/11010231.html