zoukankan      html  css  js  c++  java
  • 国庆补提二

    naipc 2019

    这道题需要用到扫描线的思想。

    首先我们用结构体存东西,存的是矩形的上下边

    也就是我们每读入一对坐标,就有

    b[++tot]={x1,x2,y1,-1}下面一条

    b[++tot]={x1,x2,y2,1}上面一条

    然后我们还要根据这个y从小到大排序这样下来,就可以看作以下画面

    那这个-11的作用,就是用来线段树用的

    例如我们现在有一个矩形,如下图,那么读入第一条,我们就会进行更新,更新线段树中包含坐标34这个点

    值为-1

    然后读入第二条边,更新34,值为1,会发现区间和就为0了,也就是说区间和不为0,那就说明有其他矩形的边一念之插给插进来,

    也就是所谓的相交了。

    如果仅仅这样是无法判断不包括内含这个状态,也就是题目说以下这种情况不算,

    所以我们进行的是单点更新,这样在查询其他线条时这条线条需要包括住下面线条的坐标,这样查询出来才会有不等于0的值,也就是表示相交

    然后就是他的坐标太广,所以我们要离散下的x坐标。

    然后就是,

    要先查询底边再更新该边,查询顶边那就得先更新再查询。

    你设想下底边如果更新后再查询就没意义了,然后顶边是用来抵消掉一个矩形的区间的,所以我们得先更新再查询

    /

    G - Intersecting Rectangles
    
    题意:给定n个顶点坐标值不重复的矩形,问是否有矩形相交(不包括内含)。
    
    题解:线段树扫描线。将每个矩形拆成上下两条线,下边的线对两端点+1,上边的线对两端点-1。如果扫到某条线发现区间和不为0,则说明相交。坐标需要离散化。
    
    #include <vector>
    #include <cstdio>
    #include <algorithm>
    #define fopi freopen("in.txt", "r", stdin)
    #define fopo freopen("out.txt", "w", stdout)
    using namespace std;
    typedef long long LL;
    typedef long double ld;
    const int maxn = 2e5 + 10;
    
    struct Seg{
        int l, r, h, id;
        bool operator < (const Seg& rhs) {
            return h < rhs.h;
        }
    };
    vector<Seg> S;
    vector<int> V;
    
    struct SegTree {
        struct Node {
            int l, r, sum;
        }t[maxn*4];
    
        void build(int id, int l, int r) {
            t[id].l = l, t[id].r = r;
            if (l == r) return;
            int mid = (l+r) / 2;
            build(id*2, l, mid);
            build(id*2+1, mid+1, r);
        }
    
        void update(int id, int x, int val) {
            if (t[id].l == t[id].r) { t[id].sum += val; return;}
            int mid = (t[id].l + t[id].r) / 2;
            if (x <= mid) update(id*2, x, val);
            else update(id*2+1, x, val);
            t[id].sum = t[id*2].sum + t[id*2+1].sum;
        }
    
        int query(int id, int l, int r) {
            if (t[id].l == l && t[id].r == r) return t[id].sum;
            int mid = (t[id].l + t[id].r) / 2;
            if (r <= mid) return query(id*2, l, r);
            else if (l > mid) return query(id*2+1, l, r);
            else return query(id*2, l, mid) + query(id*2+1, mid+1, r);
        }
    }ST;
    
    bool cmp(Seg a, Seg b) {
        return a.h < b.h;
    }
    
    int n, x1, y1, x2, y2;
    int main() {
        scanf("%d", &n);
        for (int i = 1; i <= n; i++) {
            scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
            S.push_back({x1, x2, y1, 1});
            S.push_back({x1, x2, y2, -1});
            V.push_back(x1), V.push_back(x2);
        }
    
        n *= 2;
    
        ST.build(1, 1, n);
    
        sort(S.begin(), S.end(), cmp);
        sort(V.begin(), V.end());
    
        int ans = 0;
        for (auto s : S) {
            int x = lower_bound(V.begin(), V.end(), s.l) - V.begin() + 1,
                y = lower_bound(V.begin(), V.end(), s.r) - V.begin() + 1;
    
            if (s.id == 1) ans |= ST.query(1, x, y) != 0;
            ST.update(1, x, s.id);
            ST.update(1, y, s.id);
            if (s.id == -1) ans |= ST.query(1, x, y) != 0;
        }
    
        printf("%d\n", ans != 0);
    }
    

    J - Subsequences in Substrings

    题意:给定两个字符串,求第一个字符串中有多少子串包含第二个字符串构成的子序列。

    直接暴力

      

    #include<cstdio>
    #include<string>
    #include<iostream>
    using namespace std;
    typedef long long ll;
    string s,t;
    const int maxn = 4e5+10;
    void solve()
    {
        cin>>s;
        cin>>t;
        ll lenn=s.size();
        ll lenm=t.size();
        ll ans=0,pos=-1;
        while(1)
        {
            int star,endd;
            star=s.find(t[0],pos+1);
            if(star==-1)break;
            endd=star;
            for(int i=1;i<lenm;i++){
            endd=s.find(t[i],endd+1);
            if(endd==-1)break;
            }
            if(endd==-1)break;
            ans+=(star-pos)*(lenn-endd);
            pos=star;
        }
        printf("%lld\n",ans);
    }
    int main()
    {
        ios::sync_with_stdio(false);
    
        solve();
        return 0;
    }
    

     D - It's a Mod, Mod, Mod, Mod World

    类欧几里得模板https://www.cnblogs.com/asdfsag/p/11393783.html

    题意:计算∑i=1n[(p⋅i)modq]
    
    
    
    
    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int N=1e5+10;
    int p,q,n;
    ll f(ll a,ll b,ll c,ll n) {
        if(!a)return (n+1)*(b/c);
        if(a>=c||b>=c)return f(a%c,b%c,c,n)+n*(n+1)/2*(a/c)+(n+1)*(b/c);
        ll m=(a*n+b)/c;
        return n*m-f(c,c-b-1,a,m-1);
    }
    int main() {
        int T;
        for(scanf("%d",&T); T--;) {
            scanf("%d%d%d",&p,&q,&n);
            printf("%lld\n",(ll)n*(n+1)/2*p-f(p,0,q,n)*q);
        }
        return 0;
    }
    

      

    题意:从nn个点中选择kk个点构成多边形,问期望面积。

    题解:如果能够确定两个点,那么可以从这两个点之间选择k2k−2个点来构成一个kk边形。所以可以枚举两个点,计算这两个点被选入构成凸包的概率和对凸包贡献的面积。

    #include <bits/stdc++.h>
    #define fopi freopen("in.txt", "r", stdin)
    #define fopo freopen("out.txt", "w", stdout)
    using namespace std;
    typedef long long LL;
    typedef long double ld;
    const int maxn = 2500 + 10;
    
    struct Point {
        ld x, y;
    }a[maxn];
    
    ld C[maxn][maxn];
    
    void getC(int n) {
        C[0][0] = 1;
        for (int i = 1; i <= n; i++) {
            C[i][0] = 1;
            for (int j = 1; j <= i; j++)
                C[i][j] = C[i-1][j] + C[i-1][j-1];
        }
    }
    
    ld Cross(Point a, Point b) {
        return a.x*b.y - a.y*b.x;
    }
    
    int n, k;
    int main() {
        ios::sync_with_stdio(false);
    
        cin >> n >> k;
        getC(n);
    
        for (int i = 1; i <= n; i++)
            cin >> a[i].x >> a[i].y;
    
        ld ans = 0;
        for (int i = 1; i <= n; i++)
        for (int j = k-1; j <= n-1; j++) {
            int t = i+j;
            if (t > n) t -= n;
            ans += Cross(a[i], a[t]) * C[j-1][k-2] / C[n][k];
        }
    
        printf("%.7Lf\n", ans/2);
    }
  • 相关阅读:
    windows快速安装redis
    Tensorflow教程(3)什么是张量?什么是数据流图?
    Tensorflow教程(2)Tensorflow的常用函数介绍
    Tensorflow教程(1)Tensorflow的下载和安装
    oracle获取当天时间的最开始的时间和最结尾的时间
    kindeditor在线文本编辑器过滤HTML的方法
    用PHP抓取淘宝商品的用户晒单评论+图片实例
    用PHP抓取百度贴吧邮箱数据
    微信公众号天气查询接口实例
    【Python】自动化升级所有pip安装的包
  • 原文地址:https://www.cnblogs.com/hgangang/p/11621105.html
Copyright © 2011-2022 走看看