Area Sums in Convex Polygons PLYARSM Solution Codechef

Area Sums in Convex Polygons PLYARSM Solution

You are given a convex polygon PP with NN vertices. The vertices (in clockwise order) are v1,v2,…vNv1,v2,…vN. The coordinates of vivi are (xi,yi)(xi,yi). All vertices have integer coordinates.

diagonal of PP is a line segment ll joining two distinct vertices vivi and vjvj of PP, such that ll is not already an edge of PP. Every diagonal of PP splits it into two smaller convex polygons, both having positive areas.

The evenness of a diagonal of PP is the minimum of the areas of the two parts obtained when the polygon PP is cut along this diagonal.

Let SS be the sum of the evenness of all diagonals of PP.

Find the value of 2S(mod998244353)2S(mod998244353).

It can be shown that for all polygons PP with integer coordinates, the value 2S2S is an integer.

Input Format

  • The first line of input contains an integer TT, denoting the number of test cases. The description of TT test cases follows.
  • The first line of each test case contains an integer NN, the number of vertices of the convex polygon PP. This is followed by NN lines describing the points of the convex polygon, in clockwise order.
  • The ithith subsequent line contains two space-separated integers, xi,yixi,yi — the coordinates of vivi.

Output Format

For each test case, print a new line with a single integer, the answer as per the problem statement.

Constraints

  • 1≤T≤1051≤T≤105
  • 3≤N≤1053≤N≤105
  • The sum of NN over all test cases does not exceed 106106
  • The given polygon PP is convex
  • Every coordinate is an integer whose absolute value does not exceed 108108

Subtasks

Subtask #1 ( 5 points): Sum of NN over all test cases does not exceed 500500

Subtask #2 (15 points): Sum of NN over all test cases does not exceed 20002000

Subtask #3 (80 points): Original constraints

Sample Input 1

4
4
-1 0
0 1
1 0
0 -1

4
-100000 0
0 100000
100000 0
0 -100000
3
0 0
0 1
1 0

5
-87260 82619
-59348 68595
86583 -16668
85637 -45559
-49307 -31316

Sample Output 1 

4
70225880
0
667956140

Explanation

Test case 11: The given polygon is a square with side length 2–√2. There are only two diagonals, both are identical and split the polygon equally into two halves each with area (2√)22=1(2)22=1. Thus S=min(1,1)+min(1,1)=2S=min(1,1)+min(1,1)=2. The value of 2S(mod998244353)2S(mod998244353) is thus 44.

Test case 22: The given polygon is identical to the previous case, except that all coordinates are multiplied by 105105. Therefore the given sum gets multiplied by (105)2(105)2. Make sure you output the sum modulo 998244353998244353. Here 2S=4⋅10102S=4⋅1010 and 4⋅1010(mod998244353)=702258804⋅1010(mod998244353)=70225880.

Test case 33: There are no diagonals in this polygon, and so the answer is 00.

SOLUTION

Program: Area Sums in Convex Polygons PLYARSM Solution in C++

#include<bits/stdc++.h>
#include<math.h>
using namespace std;
 
#define pb push_back
#define pf push_front
#define mp make_pair
#define pi vector <pair<int, ll >>
#define ll long long int
#define mod 998244353
#define fi first
#define Endl endl 
#define se second
#define all(a) a.begin(),a.end()
#define in(n) ll n;cin>>n
#define in2(n,k) ll n,k; cin>>n>>k
 


bool ispow(ll a){
    ll f=1;
    if(a==1){
        return false;
    }
    while(a!=1){
        if(a%2){
            f=0;
            break;
        }
        a/=2;
    }
    if(f)
        return true;
    else
        return false;
}


struct DSU{
      
      vector<int> parent;
      vector<set<int>> box;

      void initialize(int n){

          parent.resize(n);
          iota(all(parent),0); 
          box.resize(n);
          for(int i=0;i<n;i++){

            box[i].clear();
            box[i].insert(i);
        }
      }

      int pr(int a){
        if(parent[parent[a]]!=parent[a])
        parent[a]=pr(parent[a]);
           return parent[a];
      }

      void merge(int a,int b){

              a=pr(a);
              b=pr(b);

              if(a==b)
                return;
              if(box[b].size()>box[a].size())
                  swap(a,b);

              parent[b]=a;

              for(auto u : box[b])
                box[a].insert(u);

              box[b].clear();
              return;
      }

};

struct coord{
    ll x;
    ll y;
};

inline ll triangleArea(coord a,coord b,coord c){
        return (abs((a.x*(b.y-c.y))+(b.x*(c.y-a.y))+(c.x*(a.y-b.y))));
}

 
int main(){
 
    ios_base::sync_with_stdio(0);
    cin.tie(NULL);
    cout.tie(NULL);

    ll t=1;
    cin>>t;
    while(t--){
           in(n);

           vector<coord> v(n);

           for(int i=0;i<n;i++)
            cin>>v[i].x>>v[i].y;

          if(n==3){
            cout<<0<<endl;
          }

          else{
              
              ll tot=0;
              ll kri=0;

              vector<ll> prod(n,0),pre(n,0),prepre(n,0),px(n,0),py(n,0),pxy(n,0);

              px[0]=(v[0].x+mod)%mod;
              py[0]=(v[0].y+mod)%mod;
              pxy[0]=(v[0].x*v[0].y+mod)%mod;
              if(pxy[0]<0)
                pxy[0]+=mod;

              for(int i=1;i<n;i++)
                px[i]=(px[i-1]+v[i].x+mod)%mod;
              for(int i=1;i<n;i++)
                py[i]=(py[i-1]+v[i].y+mod)%mod;
               for(int i=1;i<n;i++)
                pxy[i]=(pxy[i-1]+(v[i].y*v[i].x)+(mod))%mod;



              for(int i=2;i<n;i++){
                   tot+=triangleArea(v[0],v[i-1],v[i]);
              }

              for(int i=0;i+1<n;i++){
                  prod[i]=(v[i].x+v[i+1].x)*(v[i].y-v[i+1].y);
              }

              pre[0]=prod[0];

              for(int i=1;i+1<n;i++){
                pre[i]=pre[i-1]+prod[i];
            }

            prepre[0]=(pre[0]+(mod))%mod;
            if(prepre[0]<0)
                prepre[0]+=mod;

              for(int i=1;i+1<n;i++){
                prepre[i]=(prepre[i-1]+pre[i]+mod)%mod;
            }

             for(int v1=0;v1<1;v1++){

                   ll temp=0;
                   for(int v2=v1+2;v2<n;v2++){
                       temp+=triangleArea(v[v1],v[v2-1],v[v2]);
                       kri+=min(temp,tot-temp);
                       kri=kri%mod;
                   }
              }


              for(int v1=1;v1+2<n;v1++){
                   
                   ll hi=n-1;
                   ll lo=v1+2;
                   ll idx=lo-1;

                   while(hi>=lo){
                        ll mid=(hi+lo)/2;
                        ll curr=pre[mid-1]-pre[v1-1];
                        curr+=(v[v1].x+v[mid].x)*(v[mid].y-v[v1].y);
                        if(curr<=tot-curr){
                            lo=mid+1;
                            idx=max(idx,mid);
                        }

                        else{
                             hi=mid-1;
                        }
                   }

                    
                   ll add=0;

                    ll p=tot%mod;
                    p=(p*(n-1-idx))%mod;

                   if(idx>=v1+2){
                   ll temp=(prepre[idx-1]-prepre[v1]+mod)%mod;

                   ll z=(pre[v1-1]+mod)%mod;
                   z*=(idx-v1-1);
                   z%=mod;
                   temp=(temp-z+mod)%mod;
                   z=((v[v1].x)*((py[idx]-py[v1+1]+mod)%mod))%mod;
                   ll g=(idx-v1-1);
                   g*=(v[v1].x*v[v1].y+mod)%mod;
                   g%=mod;
                   ll h=(pxy[idx]-pxy[v1+1]+mod)%mod;
                   ll r=(((v[v1].y)*((px[idx]-px[v1+1]+mod)%mod))%mod);
                   temp=(temp-r-g+h+z+mod)%mod;
                   add=temp;

                   kri+=temp;
                   kri%=mod;

               }

                idx=n-1;

               ll temp=(prepre[idx-1]-prepre[v1]+mod)%mod;
                   ll z=(pre[v1-1]+mod)%mod;
                   z*=(idx-v1-1);
                   z%=mod;
                   temp=(temp-z+mod)%mod;
                   z=((v[v1].x)*((py[idx]-py[v1+1]+mod)%mod))%mod;
                   ll g=(idx-v1-1);
                   g*=(v[v1].x*v[v1].y+mod)%mod;
                   g%=mod;
                   ll h=(pxy[idx]-pxy[v1+1]+mod)%mod;
                   ll r=(((v[v1].y)*((px[idx]-px[v1+1]+mod)%mod))%mod);
                   temp=(temp-r-g+h+z+mod)%mod;
                   temp=(temp-add+mod)%mod;

                   kri+=p;
                   kri%=mod;

                   kri=(kri-temp+mod)%mod;

              }

          cout<<kri;

       
        cout<<endl;
    }

    }
    return 0;
}

February Long 2022 – II (Rated for Div 3)

Leave a Comment

five × five =