ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

【ZJSU - 大红大紫:ACM - Template】比赛用模板06:多项式与几何

2022-09-10 12:30:10  阅读:172  来源: 互联网

标签:p2 06 int 大红大紫 top ZJSU return ans fff


多项式与几何

快速数论变换 \(\tt NTT\)

\(\mathcal O(N * logN)\) 。

namespace poly{
    const int M = 998244353,G = 3,Gi = 332748118;
    const int N = 5000000;
    int n,m;
    int res,ans[5000005];
    int limit = 1;
    int L;
    int RR[5000005];
    LL a[N],b[N];
    LL ps(LL n,LL k){
        LL res = 1;
        while(k){
            if (k & 1) res = res * n % M;
            n = n * n % M;
            k >>= 1;
        }
        return res;
    }
    LL inv(LL x){return ps(x,M - 2);}
    void NTT(LL *A ,int type){
        for(int i = 0; i < limit; i++){
            if (i < RR[i]){
                swap(A[i],A[RR[i]]);
            }
        }
        for(int mid = 1; mid < limit; mid <<= 1){
            LL wn = ps(G,(M - 1) / (mid * 2));
            if (type == -1){
                wn = ps(wn,M - 2);
            }
            for(int len = mid << 1,pos = 0; pos < limit; pos += len){
                LL w = 1;
                for(int k = 0; k < mid ; ++k,w = (w * wn) % M){
                    int x = A[pos + k],y = w * A[pos + mid + k] % M;
                    A[pos + k] = (x + y) % M;
                    A[pos + k + mid] = (x -y + M) % M;
                }
            }
        }
        if (type == -1){
            LL limit_inv = inv(limit);
            for(int i = 0; i < limit; i++){
                A[i] = (A[i] * limit_inv) % M;
            }
        }
    }
    void poly_mul(LL *a,LL *b,int deg){
        for(limit = 1, L = 0; limit <= deg; limit <<= 1)L ++;
        for(int i = 0; i < limit ; i++){
            RR[i] = (RR[i >> 1] >> 1) | ((i & 1) << (L - 1));
        }
        NTT(a,1);
        NTT(b,1);
        for(int i = 0; i < limit; i++){
            a[i] = a[i] * b[i] % M;
        }
        NTT(a,-1);
    }    
}
using namespace poly;

int main(){
    cin >> n >> m;
    for(int i = 0; i <= n; i++){
        cin >> a[i];
    }
    for(int i = 0; i <= m; i++){
        cin >> b[i];
    }
    poly_mul(a,b,n+m);
    for(int i = 0; i <= n + m; i++){
        cout << a[i] << " \n"[i == n + m];
    }
    return 0;
}

凸包、二维凸包与旋转卡壳

\(\mathcal{Provided \ by \ \pmb{Wcj}}\) 。

struct fff { double x, y; } p[maxn], ans[maxn], p0;
double d(fff p1, fff p2) { // 距离公式
    return sqrt((p2.y - p1.y) * (p2.y - p1.y) + (p2.x - p1.x) * (p2.x - p1.x));
}
LL dd(fff p1, fff p2) { // 距离公式
    return (p2.y - p1.y) * (p2.y - p1.y) + (p2.x - p1.x) * (p2.x - p1.x);
}
double check(fff a1, fff a2, fff b1, fff b2) { // 叉积
    return (a2.x - a1.x) * (b2.y - b1.y) - (b2.x - b1.x) * (a2.y - a1.y);
}
inline bool cmp(fff a, fff b) {
    double A = atan2(a.y - p0.y, a.x - p0.x);
    double B = atan2(b.y - p0.y, b.x - p0.x);
    if (A != B) return A < B;
    else if (a.x == b.x) return a.y < b.y;
    else return a.x < b.x;
}
inline long long chaji(int x1, int y1, int x2, int y2) {
    return (1LL * x1 * y2 - 1LL * x2 * y1);
}
inline long long fx(fff a, fff b, fff c) {
    return chaji((b.x - a.x), (b.y - a.y), (c.x - a.x), (c.y - a.y));
}
inline void Find() // 二维凸包
{
    p0 = (fff){INF, INF};
    int k = 0;
    for (int i = 0; i < n; ++i)
        if (p0.y > p[i].y || (p0.y == p[i].y && p0.x > p[i].x))
            p0 = p[i], k = i;
    swap(p[k], p[0]);
    sort(&p[1], &p[n], cmp);
    ans[0] = p[0], ans[1] = p[1], top = 1;
    for (int i = 2; i < n;) {
        if (top && fx(ans[top - 1], p[i], ans[top]) >= 0) top--;
        else ans[++top] = p[i++];
    }
}
int get() { //旋转卡壳
    LL c = 0;
    if (top == 1) return dd(ans[0], ans[1]);
    ans[++ top] = ans[0];
    int j = 2;
    for (int i = 0; i < top; ++i) {
        while (fx(ans[i], ans[i + 1], ans[j]) < fx(ans[i], ans[i + 1], ans[j + 1]))
            j = (j + 1) % top;
        c = max(c, max(dd(ans[i], ans[j]), dd(ans[i + 1], ans[j])));
    }
    return c;
}

封装待更新(参考杭电第八场1010)


判断线段是否相交:快速排斥+跨立实验

struct Node { int x, y; } a, b, c, d;
bool judge(Node a, Node b, Node c, Node d) { 
    if (!(min(a.x, b.x) <= max(c.x, d.x) && min(c.x, d.x) <= max(a.x, b.x) &&
          min(a.y, b.y) <= max(c.y, d.y) && min(c.y, d.y) <= max(a.y, b.y)))
        return false;//快速排斥
    
    double u, v, w, z;//跨立实验
    u = (c.x - a.x) * (b.y - a.y) - (b.x - a.x) * (c.y - a.y); // AC×AB
    v = (d.x - a.x) * (b.y - a.y) - (b.x - a.x) * (d.y - a.y); // AD×AB
    w = (a.x - c.x) * (d.y - c.y) - (d.x - c.x) * (a.y - c.y); // CA×AB
    z = (b.x - c.x) * (d.y - c.y) - (d.x - c.x) * (b.y - c.y); // CB×AB

    if (u * v <= 1e-9 && w * z <= 1e-9) return true;
    return false;
}
int main() {
    int t;
    cin >> t;
    while (t--) {
        cin >> a.x >> a.y >> b.x >> b.y >> c.x >> c.y >> d.x >> d.y;
        if (judge(a, b, c, d)) printf("YES\n");
        else printf("NO\n");
    }
    return 0;
}

标签:p2,06,int,大红大紫,top,ZJSU,return,ans,fff
来源: https://www.cnblogs.com/WIDA/p/16676286.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有