zoukankan      html  css  js  c++  java
  • ASC45

    A

    题意 要求构造集合$A,B$, 使得$A+A$与$B+B$相同

    只有$n$为$2$的幂时合法, 构造可以初始化$A_0=1,B_0=2$

    然后让$A_{i+2^x}=B_{i}+2^{x+1},B_{i+2^x}=A_{i}+2^{x+1}$

    #include <bits/stdc++.h>
    #define REP(_i,_a,_n) for(int _i=_a;_i<=_n;++_i)
    #define PER(_i,_a,_n) for(int _i=_n;_i>=_a;--_i)
    using namespace std;
    int main() {
        freopen("analogous.in","r",stdin);
        freopen("analogous.out","w",stdout);
        int n;
        while (cin>>n,n) {
            if ((n&-n)!=n) puts("No");
            else {
                puts("Yes");
                vector<int> v[2];
                v[0].push_back(1),v[1].push_back(2);
                for (int x=2; v[0].size()!=n; x<<=1) {
                    int sz = v[0].size();
                    REP(i,0,sz-1) v[0].push_back(v[1][i]+x),v[1].push_back(v[0][i]+x);
                }
                for (int t:v[0]) cout<<t<<' ';puts("");
                for (int t:v[1]) cout<<t<<' ';puts("");
            }
        }
    }
    View Code

    B

    题意 $f$为分段线性函数, 求最小的区间$[L,R]$, 满足$P(Lle xile R | ale f(xi)le b)ge alpha$

    预处理出所有合法区间, 然后滑动区间

    #include <iostream>
    #include <queue>
    #include <cmath>
    using namespace std;
    #define db double
    #define abs(x) ((x)>0?(x):(-x))
    #define LL long long
    #define mp make_pair
    #define pb push_back
    #define fi first
    #define se second
    const db EPS = 1e-9;
    const db INF = 1e18;
    const db PI = acos(-1.0);
    inline double torad(double deg) { return deg / 180 * PI; }//转弧度
     
    inline int dcmp(double x)
    {
        if(fabs(x) < EPS) return 0;
        return x < 0 ? -1 : 1;
    }
    struct Point{
        db x, y;
        Point(db _x = 0, db _y = 0) : x(_x), y(_y){}
        inline void read(){
            scanf("%lf %lf", &x, &y);
        }
    };
    // 过两点p1, p2的直线一般方程ax+by+c=0
    // (x2-x1)(y-y1) = (y2-y1)(x-x1)
    inline void GetLineGeneralEquation(Point p1, Point p2, double &a, double &b, double &c)
    {
        a = p2.y - p1.y;
        b = p1.x - p2.x;
        c = -a * p1.x - b * p1.y;
    }
    const int N = 1e5+10;
    int n;
    Point p[N];
    double a,b,x;
    pair<double,double> f[N];
    
    int main() {
        freopen("bayes.in","r",stdin);
        freopen("bayes.out","w",stdout);
        while (scanf("%d", &n), n) {
            scanf("%lf%lf%lf", &a, &b, &x);
            for (int i=0; i<=n; ++i) {
                scanf("%lf%lf", &p[i].x, &p[i].y);
            }
            int cnt = 0;
            double tot = 0;
            for (int i=1; i<=n; ++i) {
                double u,v,w;
                GetLineGeneralEquation(p[i-1],p[i],u,v,w);
                double l = p[i-1].x, r = p[i].x;
                //ax+by+c=0
                //x=(-c-by)/a
                double l1 = (-w-v*a)/u, r1 = (-w-v*b)/u;
                if (l1>r1) swap(l1,r1);
                l = max(l, l1), r = min(r, r1);
                if (l<=r) f[++cnt] = {l,r}, tot += r-l;
            }
            tot *= x;
            int now = 1;
            double l, r, len = 0;
            double ans = 1e18;
            for (int i=1; i<=cnt; ++i) {
                if (f[i].second-f[i].first>=tot) {
                    l = f[i].first, r = f[i].first+tot;
                    break;
                }
                while (now<=cnt&&len<tot) {
                    len += f[now].second-f[now].first;
                    ++now;
                }
                if (len>=tot) {
                    double ret = f[now-1].second-f[i].first-len+tot;
                    if (ret<ans) ans = ret, l = f[i].first, r = f[now-1].second-len+tot;
                }
                len -= f[i].second-f[i].first;
            }
            printf("%.12lf %.12lf
    ", l, r);
        }
    }
    View Code

    C

    题意 求所有长$n$, 不存在$i<j<k$使得$a_k<a_i<a_j$的$ascentspace sequences$个数

    从前往后填数, 维护每种数出现的状态, 始终把当前能填的最小数当做最低位, 可以发现状态会有很多重复的, 记忆化一下就可以了

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef tuple<int,int,int,ll> state;
    map<state,ll> mp;
    ll solve(int d, int mx, int pre, ll s) {
        state now(d,mx,pre,s);
        if (mp.count(now)) return mp[now];
        if (!d) return 1;
        ll ans = 0;
        int mi = 0;
        for (int i=0; i<=mx; ++i) {
            ans += solve(d-1,mx-mi+(i>pre),i-mi,(s|1ll<<i)>>mi);
            if (s>>i&1) mi = i;
        }
        return mp[now]=ans;
    }
    int main() {
        freopen("catalian.in","r",stdin);
        freopen("catalian.out","w",stdout);
        int n, clk = 0;
        while (cin>>n,n) cout<<"Case #"<<clk<<": "<<solve(n-1,1,0,1)<<endl;
    }
    View Code

    D

    题意 要求构造一个$n$点的有向图, 点$n-1$是家, 点$n$是酒吧, 其余点出度为$2$, 初始有一个酒鬼在点$1$, 每一步酒鬼等概率走向一个点, 要求最终酒鬼回家的概率为$frac{p}{q}$

    考虑二进制即可, 比如$q=13$, 那么构造$f=frac{f}{16}+frac{f}{8}+frac{1}{4}+frac{1}{2}$, $f=frac{12}{13}$

    那么就可以用$lceillog_2{q} ceil$个点构造出$frac{q-1}{q}$, 然后再递归构造$frac{q-2}{q-1}$, 以此类推

    这样构造出$frac{p}{q}$大约要$qlceillog_2{q} ceille 1000$可以满足条件

    #include <bits/stdc++.h>
    #define REP(_i,_a,_n) for(int _i=_a;_i<=_n;++_i)
    #define PER(_i,_a,_n) for(int _i=_n;_i>=_a;--_i)
    using namespace std;
    const int N = 1e5+10;
    int tot,L[N],R[N],f[N],g[N],ID[N];
    int solve(int p, int q, int s) {
        int x = 1;
        while ((1<<x)<q) ++x;
        int y = (1<<x)-q, now = tot+1;
        PER(i,0,x-1) {
            ++tot;
            L[tot] = y>>i&1?now:s;
            R[tot] = i?tot+1:1;
        }
        if (p!=q-1) return solve(p,q-1,now);
        return now;
    }
    void gao(int x, int y) {
        if (x==y) return;
        REP(i,1,tot) {
            if (L[i]==x) f[i] = y;
            else if (L[i]==y) f[i] = x;
            else f[i] = L[i];
            if (R[i]==x) g[i] = y;
            else if (R[i]==y) g[i] = x;
            else g[i] = R[i];
        }
        REP(i,1,tot) {
            if (i==x) L[i] = f[y], R[i] = g[y];
            else if (i==y) L[i] = f[x], R[i] = g[x];
            else L[i] = f[i], R[i] = g[i];
        }
        REP(i,1,tot) {
            if (ID[i]==x) ID[i] = y;
            else if (ID[i]==y) ID[i] = x;
        }
    }
    int main() {
        freopen("drunkard.in","r",stdin);
        freopen("drunkard.out","w",stdout);
        int p,q;
        while (cin>>p>>q,p||q) {
            L[1] = R[1] = L[2] = R[2] = 0;
            tot = 2;
            int x = solve(p,q,2);
            REP(i,1,tot) ID[i] = i;
            gao(1,x),gao(tot-1,ID[2]),gao(tot,ID[1]);
            printf("%d
    ", tot);
            REP(i,1,tot-2) printf("%d %d
    ",L[i],R[i]);
        }
    }
    View Code

    F

    题意 给定一个$n$点$m$条边的图, 保证点$1$与其他所有点相连, 要求给每条边标号, 使得标号是$[1,m]$的排列, 并且每个点邻接边标号和不相同

    先将与$1$不与$1$相连的边赋任意权值, 然后排序通过与$1$相连的边调整即可

    #include <bits/stdc++.h>
    #define REP(_i,_a,_n) for(int _i=_a;_i<=_n;++_i)
    #define PER(_i,_a,_n) for(int _i=_n;_i>=_a;--_i)
    using namespace std;
    typedef long long ll;
    const int N = 1e6+10;
    int n, m, f[N], ID[N];
    pair<ll,int> val[N];
    int main() {
        freopen("flights.in","r",stdin);
        freopen("flights.out","w",stdout);
        while (scanf("%d%d", &n, &m), n||m) {
            REP(i,1,n) val[i].first=0,val[i].second=i;
            int now = 1;
            REP(i,1,m) {
                int u, v;
                scanf("%d%d", &u, &v);
                if (u>v) swap(u,v);
                if (u!=1) {
                    val[u].first += now;
                    val[v].first += now;
                    f[i] = now;
                    ++now;
                }
                else ID[v] = i;
            }
            sort(val+1,val+1+n);
            REP(i,2,n) f[ID[val[i].second]]=now++;
            puts("Yes");
            REP(i,1,m) printf("%d ", f[i]);puts("");
        }
    }
    View Code
  • 相关阅读:
    IIT(ISM) Virtual Farewell E Dictator's plan for Valentine's day! 二分
    HDU
    LightOJ
    HDU 4407 Sum 容斥原理
    HDU 4686 Arc of Dream 矩阵快速幂
    uoj418
    Gym101237C The Palindrome Extraction Manacher
    Codeforces 100032 K
    codechef Suffix Palindromes
    Codeforces 932G Palindrome Partition
  • 原文地址:https://www.cnblogs.com/fs-es/p/13411139.html
Copyright © 2011-2022 走看看