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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

[CQOI2014]数三角形 组合数 + 容斥 + gcd

發布時間:2023/11/27 生活经验 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [CQOI2014]数三角形 组合数 + 容斥 + gcd 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

推導過程 : 組合數+容斥原理+gcd

正確做法是暴力的一種優化,ans=所有情況 - 平行坐標軸的三點共線 - 斜線三點共線

如果快速求斜線三點共線:

首先要知道一個結論,對于點(a,b) (x,y)連成的線段而言(其中a>x,b>y),

在它們中間有gcd(a-x,b-x)-1個整點,因此基本的思路就是枚舉兩個點,

然后第3個點就是gcd(a-x,b-x)-1種可能了

至于為什么第3個點一定要在中間,是為了保證不重不漏,只用兩邊的點統計中間的點,

然而這樣復雜度太高,于是可以發現,可以將這兩個點組成的線段中左下那個端點平移至原點,

這樣相當于只要枚舉一個點,并且由于要考慮k<0的情況,因為矩形是有對稱性的,

所以要求原點+一個點 與 (0,m)+一個點 的和就可以直接2 *(原點+一個點)

由于長的一樣的線有很多,于是問題就轉化為如果求這些一樣的線的個數,

那么可以發現,這樣任意一條線,向上只能平移(n - i),向下(m - j)次,

所以可能性就為(n - i + 1) * (m - j + 1),其中+1是因為可以向上移動0個單位

但由于這里n,m一開始就加了1,所以這個式子就不用+1了

因此枚舉每個點即可

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define R register int
 4 #define LL long long
 5 LL n,m,ans,go;
 6 
 7 int gcd(int x,int y)
 8 {
 9     if(!y) return x;
10     else return gcd(y,x%y);
11 }
12 
13 void work()
14 {
15     scanf("%lld%lld",&n,&m);
16     ++n,++m;//因為是一個網格,所以真正的坐標系其實有(n+1,m+1)
17     go=n*m;
18     ans=go * (go - 1) * (go - 2) / 6 - n * m * (m - 1) * (m - 2) / 6 - m * n * (n - 1) * (n - 2) / 6;//記得除掉取出數列的全排列
19     for(R i=1; i<n ;i++)//因為是取了原點,所以相當于坐標系是從0開始了
20         for(R j=1; j<m ;j++)//枚舉這個點
21             ans-=(LL)2 * (LL)(gcd(i,j) - 1) * (LL)(n - i) * (LL)(m - j); 
22     printf("%lld\n",ans);
23 }
24 
25 int main()
26 {
27     freopen("in.in","r",stdin);
28     work();
29     fclose(stdin);
30     return 0;
31 }

?

轉載于:https://www.cnblogs.com/ww3113306/p/8762942.html

總結

以上是生活随笔為你收集整理的[CQOI2014]数三角形 组合数 + 容斥 + gcd的全部內容,希望文章能夠幫你解決所遇到的問題。

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