區間最大公約數
gcd + 線段樹
本題是可以用單點修改實現的 :
如果我們要求區間的\(gcd:gcd(a,b,c,d).\)
根據gcd的推論:\(gcd(a,b)=gcd(a,b-a)\)在多項中的推廣:
\(gcd(a,b,c,d)=gcd(a,b-a,c-b,d-c)\)
當我們需要修改乙個區間\((a,b,c)->(a+x,b+x,c+x):\)
\(gcd(a+x,b+x,c+x,d)=gcd(a+x,b-a,c-a).\)
因此操作乙個區間只需要保證線段樹中存的是差分,然後修改第乙個點就行了.
特別注意為了不讓本次操作對後續造成影響:還需要\(modify(1,r+1,x).\)
再考慮樹中節點維護的變數 :sum和gcd
為什麼要維護sum?
為了在修改後能正確得到第乙個數的真實值.
所以答案其實是 : \(gcd(left.sum,right.d)\)
\(left=query(1,1,l)\)
\(right=query(1,l+1,r)\)
#include using namespace std;
#define io ios::sync_with_stdio(false);cin.tie(0); cout.tie(0);
inline int lowbit(int x)
#define ll long long
#define ull unsigned long long
#define pb push_back
#define pii pair#define vit vector#define x first
#define y second
#define inf 0x3f3f3f3f
const int n = 5e5 + 10;
ll a[n], b[n];
int n, m;
struct node tr[n * 4];
ll gcd(ll a, ll b)
void pushup(node &t, node &l, node &r)
void pushup(int u)
void build(int u, int l, int r) ;
else ;
int mid = l + r >> 1;
build(u << 1, l, mid);
build(u << 1 | 1, mid + 1, r);
pushup(u);
}}void modify(int u, int x, ll v) ;
} else
}node query(int u, int l, int r)
}int main() else ;
if (l + 1 <= r) right = query(1, l + 1, r);
cout << abs(gcd(left.sum, right.d)) << '\n';}}
return 0;
}
最大公約數
1.執行最大公約數的常用演算法,並新增異常處理模組 如輸入非法等 在基礎程式的基礎上,可以考慮手動輸入所有數字或者利用隨機數產生數字,分別加入異常處理模組。注 隨機數的產生方法 srand 的作用是提供乙個種子。然後呼叫rand 其格式為int rand void 它會根據提供給srand 的種子值...
最大公約數
最大公因數 greatest common divisor 也稱最大公約數 最大公因子,指兩個或多個整數共有約數中最大的乙個。a,b的最大公約數記為 a,b 同樣的,a,b,c的最大公約數記為 a,b,c 多個整數的最大公約數也有同樣的記號。求最大公約數有多種方法,常見的有質因數分解法 短除法 輾轉...
最大公約數
求兩數的最大公約數 簡單嗎?簡單!用多種方法求,可以嗎?emmmmm.應該可以吧?相信絕大多數人都知道求最大公約數的如下 所示的這種方法 include includeint commondivisor int x,int y min return min int main 先判斷兩個數的大小,將較...