日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

HihoCoder - 1879 Rikka with Triangles(极角排序求所有锐角三角形的面积)

發布時間:2024/4/11 编程问答 45 豆豆
生活随笔 收集整理的這篇文章主要介紹了 HihoCoder - 1879 Rikka with Triangles(极角排序求所有锐角三角形的面积) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題目鏈接:點擊查看

題目大意:給出 n ( n <= 2000 ) 個點,求出所有不同的銳角三角形的面積

題目分析:n^3 暴力枚舉肯定是不可以的,和之前寫過的一個題目思路很像:HDU-5784

所以這個題目的思路就是,枚舉所有的角,如果是銳角的話貢獻為 1,如果是鈍角或直角的話貢獻為 -2,最后相加除以 3 即可,可行性的證明可以直接列舉一下三種三角形的情況:

  • 銳角三角形:三個角都是銳角,計算出的貢獻為 3 倍的面積
  • 直角三角形:一個角為直角,其余兩個角都為銳角,直角的提供?-2 倍的貢獻,其余兩個銳角提供 2 倍的貢獻,可以相互抵消
  • 鈍角三角形:同直角三角形可以抵消
  • 這樣的話利用極角排序枚舉每個角,將時間復雜度優化到 n^2logn,具體就是,O( n ) 枚舉一個點記為?A,O( nlogn ) 以點 A 為中心進行極角排序,隨后 O( n ) 枚舉一條向量 AB,雙指針尋找另一個向量的可行邊界 AC,這樣就可以快速計算出角 BAC 的貢獻了,因為點積和叉積都滿足分配率,就可以將叉積求解三角形面積的公式進行化簡,用前綴和來進行輔助計算即可

    值得一提的是,點積的幾何意義是,兩個向量的方向:

  • AB * AC > 0 :角 BAC 大于 0 度,小于 90 度
  • AB * AC = 0 :角 BAC 等于 90 度,也就是 AB 垂直于 AC
  • AB * AC < 0 :角 BAC 大于 90 度,小于 180 度
  • 然后叉積的幾何意義是方向,右手定則,通俗一點來講就是在 180 度以內,兩條向量的相對位置,如果只關注叉積的數值的話,叉積的絕對值是兩個向量所組成的平行四邊形的面積

    還有就是極角排序,需要先對向量進行象限排序,如果不在同一象限的話再按照叉積排序(叉積相同且象限相同的話,怎么排都無所謂了,因為在這個題目中是都會跳過的(因為兩個向量共線,三角形的面積為 0 ,沒必要過多的計算))

    最后就是這個題目需要注意的一點了,數據范圍給的特別大,顯然用 double 是不行的了,double 的精度也就只有 1e15 的樣子,所以所有的數據都需要用 long long 來儲存,然后好多好多地方的運算都會爆 long long ,需要暫時用 __int128 來進行運算,代碼中我用小寫的 ll 代替 __int128 ,大寫的 LL 代替的 long long

    比較不錯的一道題目吧,做完之后收獲頗豐

    代碼:
    ?

    #pragma GCC optimize(2) #pragma GCC optimize("Ofast","inline","-ffast-math") //#pragma GCC target("avx,sse2,sse3,sse4,mmx") #include<iostream> #include<cstdio> #include<string> #include<ctime> #include<cmath> #include<cstring> #include<algorithm> #include<stack> #include<climits> #include<queue> #include<map> #include<set> #include<sstream> #include<cassert> #include<bitset> #include<unordered_map> using namespace std;typedef long long LL;typedef __int128 ll;typedef unsigned long long ull;const int inf=0x3f3f3f3f;const int N=2e3+100;const int mod=998244353;const int inv3=332748118;LL ans,not_ans,sumx[N<<1],sumy[N<<1];int n;inline int sgn(LL x){if(x==0)return 0;if(x < 0)return -1;else return 1; }struct Point{LL x,y;Point(){}Point(LL _x,LL _y){x = _x;y = _y;}void input(){scanf("%lld%lld",&x,&y);}bool operator == (Point b)const{return sgn(x-b.x) == 0 && sgn(y-b.y) == 0;}bool operator < (Point b)const{return sgn(x-b.x)== 0?sgn(y-b.y)<0:x<b.x;}Point operator -(const Point &b)const{return Point(x-b.x,y-b.y);}Point operator +(const Point &b)const{return Point(x+b.x,y+b.y);}//叉積ll operator ^(const Point &b)const{return (ll)x*b.y - (ll)y*b.x;}//點積ll operator *(const Point &b)const{return (ll)x*b.x + (ll)y*b.y;} }p[N],q[N<<1];inline int getxx(Point& a) {if(sgn(a.x)>0 && sgn(a.y)>=0) return 1;if(sgn(a.x)<=0 && sgn(a.y)>0) return 2;if(sgn(a.x)<0 && sgn(a.y)<=0) return 3;if(sgn(a.x)>=0 && sgn(a.y)<0) return 4; }bool cmp(Point a,Point b) {if(getxx(a)!=getxx(b))return getxx(a)<getxx(b);return sgn(a^b)>0; }void solve(int id) {for(int i=1,j=1;i<=n;i++)if(i!=id)q[j++]=p[i]-p[id];sort(q+1,q+n,cmp);int n=::n-1;for(int i=1;i<=n;i++)q[i+n]=q[i];for(int i=1;i<=n<<1;i++){sumx[i]=(sumx[i-1]+q[i].x)%mod;sumy[i]=(sumy[i-1]+q[i].y)%mod;}int j=1,k=1,l=1;//相同極角的點的位置,銳角極角的位置,鈍角極角的位置for(int i=1;i<=n;i++){while(j<i+n&&(q[i]^q[j])==0&&(q[i]*q[j])>0)j++;k=max(k,j);while(k<i+n&&(q[i]^q[k])>0&&(q[i]*q[k])>0)k++;l=max(l,k);while(l<i+n&&(q[i]^q[l])>0)l++;LL x1=(sumx[k-1]-sumx[j-1]+mod)%mod;LL y1=(sumy[k-1]-sumy[j-1]+mod)%mod;ans=(ans+((q[i].x%mod)*(y1)-(x1)*(q[i].y%mod))%mod+mod)%mod;LL x2=(sumx[l-1]-sumx[k-1]+mod)%mod;LL y2=(sumy[l-1]-sumy[k-1]+mod)%mod;not_ans=(not_ans+((q[i].x%mod)*(y2)-(x2)*(q[i].y%mod))%mod+mod)%mod;} }int main() { #ifndef ONLINE_JUDGE // freopen("data.in.txt","r",stdin); // freopen("data.out.txt","w",stdout); #endif // ios::sync_with_stdio(false);int w;cin>>w;while(w--){ans=0,not_ans=0;scanf("%d",&n);for(int i=1;i<=n;i++)p[i].input();for(int i=1;i<=n;i++)solve(i);printf("%lld\n",(ans-not_ans+mod-not_ans+mod)%mod*inv3%mod);}return 0; }

    ?

    總結

    以上是生活随笔為你收集整理的HihoCoder - 1879 Rikka with Triangles(极角排序求所有锐角三角形的面积)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。