zoukankan      html  css  js  c++  java
  • noip模拟赛

    T1 抓牛

    你在 $n$ ,牛在 $k$,你一步可以走到 $n-1,n+1,2 imes n$,问最少几步能抓到牛

    sol:dp

    $f_i$ 表示走到 $i$ 最少走了几步

    当 $i leq n - 1$ 时,显然 $f_i = f_{i+1} + 1$(因为只能一步一步走过去)

    $i$ 在 $n$ 右边时,有两种转移

    对于一个偶数,它可能是左边走过来的,或者是它的一半跳过来的

    对于一个奇数,他有可能是左边走过来的,也可能是从某位置一步跳到右边然后往左走一步

    这种 $frac{(i+1)}{2} -> (i+1) ->i$ 的怎么算呢,当然是 $f_i = f_{frac{(i+1)}{2}} + 2$

    T2 $k$阶前缀和

    求一个数列的 $k$ 阶前缀和膜$10^9+7$,$n leq 5000,k leq 10^9$

    sol:打表找规律

    打出来表,发现是一个斜着的杨辉三角,然后搞一下就可以了

    但我并不是这么推的。。

    考虑数列 $1space 0space 0space 0space 0space 0$

    一阶前缀和是$1space 1space 1space 1space 1space 1 = $$i-1 choose 0$

    二阶前缀和$i choose 1$

    三阶前缀和$i+1 choose 2$

    ...

    $k$ 阶前缀和 $i+k-2 choose k-1$

    所以预处理出这个再搞就可以了

    T3 小乔

    给一个极坐标,将 $2pi$ 分成 $2m$ 个单位角度

    每次给一个扇形,最后求至少被 $k$ 个扇形覆盖的区域面积是多少

    sol:扫描线 + 平衡树/权值线段树/差分树状数组

    主席树好像会被卡空间 qwq

    首先将跨过坐标轴的询问拆开,然后搞一个扫描线,维护一个数据结构支持单点插入、单点删除、查询被 $k$ 个扇形覆盖的区域

    每次扫描线扫到一条扇形的边的时候插入/删除

    然后怎么查询被 $k$ 个扇形覆盖的区域呢?显然是第 $k$ 大的半径内部的部分

    事实证明,平衡树 xjb 转复杂度也是对的

    只不过常数有点大...

    AK 啦好开心 qwq

    #include<bits/stdc++.h>
    #define LL long long
    using namespace std;
    inline int read()
    {
        int x = 0,f = 1;char ch = getchar();
        for(;!isdigit(ch);ch = getchar())if(ch == '-')f = -f;
        for(;isdigit(ch);ch = getchar())x = 10 * x + ch - '0';
        return x * f;
    }
    const int maxn = 100000 + 10;
    int n,k;
    LL f[maxn];
    int main()
    {
        freopen("meet.in","r",stdin);
        freopen("meet.out","w",stdout);
        n = read(),k = read();
        f[n] = 0;
        for(int i=n-1;i>=0;i--)f[i] = f[i + 1] + 1;
        for(int i=n+1;i<=k;i++)
        {
            if(i & 1) f[i] = min(f[i - 1] + 1,f[(i + 1) / 2] + 2);
            else f[i] = min(f[i / 2] + 1,f[i - 1] + 1);
        }
        cout<<f[k];
    }
    T1
    #include<bits/stdc++.h>
    #define int long long
    using namespace std;
    inline int read()
    {
        int x = 0,f = 1;char ch = getchar();
        for(;!isdigit(ch);ch = getchar())if(ch == '-')f = -f;
        for(;isdigit(ch);ch = getchar())x = 10 * x + ch - '0';
        return x * f;
    }
    const int maxn = 5010,mod = 1e9 + 7;
    int n,k;int a[maxn],s[maxn],Inv[maxn];
    inline int ksm(int x,int t)
    {
        int res = 1;
        while(t)
        {
            if(t & 1)res = res * x % mod;
            x = x * x % mod;
            t = t >> 1;
        }
        return res;
    }
    inline int inv(int x){return ksm(x,mod - 2);}
    /*sig (1~x) from (x + k - i) choose (i) * a[0][i]*/
    inline int C(int n,int m)
    {
        if(n < m || n < 0 || m < 0)return 0;
        int cur = n,ans = 1;
        for(int i=m;i>=1;i--)
        {
            (ans *= cur) %= mod;
            (ans *= Inv[i]) %= mod;
            cur--;
        }
        return ans;
    }
    int xs[maxn];
    signed main()
    {
        freopen("sum.in","r",stdin);
        freopen("sum.out","w",stdout);
        n = read();k = read() - 1;
        //for(int i=1;i<=n+k;i++)fac[i] = fac[i - 1] * i % mod;
        Inv[0] = 1;
        for(int i=1;i<=n;i++)Inv[i] = inv(i);
        for(int i=1;i<=n;i++)a[i] = read();
        //for(int i=1;i<=n;i++)a[i] -= a[i - 1];
        //for(int i=1;i<=n;i++)cout<<a[i]<<" "; 
        for(int i=1;i<=n;i++)xs[i] = C(i + k - 1,(i + k - 1) - k) % mod;
        for(int i=1;i<=n;i++)
            for(int j=1;j<=i;j++)
                (s[i] += xs[i - j + 1] * a[j]) %= mod;
        for(int i=1;i<=n;i++)printf("%lld ",s[i]);
    }
    T2
    #include<bits/stdc++.h>
    #define LL long long
    using namespace std;
    inline int read()
    {
        int x = 0,f = 1;char ch = getchar();
        for(;!isdigit(ch);ch = getchar())if(ch == '-')f = -f;
        for(;isdigit(ch);ch = getchar())x = 10 * x + ch - '0';
        return x * f;
    }
    const int maxn = 400005;
    int n,m,kk;
    int top1,top2;
    struct qwq{int l,r,R;}nega[maxn],posi[maxn];
    struct ques{int st,r;char f;bool operator < (const ques &b)const{return st<b.st;}}opts[maxn];
    
    namespace RP
    {
        struct node{int ls,rs,size,val;}tr[maxn << 2];
        int dfn,root,ops;
        inline void pushup(int x){tr[x].size=tr[tr[x].ls].size+tr[tr[x].rs].size+1;}
        inline void lt(int &x)
        {
            int k=tr[x].rs;tr[x].rs=tr[k].ls;
            tr[k].ls=x;tr[k].size=tr[x].size;
            pushup(x);
            x=k;
        }
        inline void rt(int &x)
        {
            int k=tr[x].ls;tr[x].ls=tr[k].rs;
            tr[k].rs=x;tr[k].size=tr[x].size;
            pushup(x);
            x=k;
        }
        inline int rng()
        {
            static unsigned long long seed = 233333333333333333LL;
            seed = seed + (seed << 17) + 531433123515;
            return seed;
        }
        /*
        void rp()
        {
            int x;
            for(int i=1;i<=min(n,10);i++)lt(x = rng() % n + 1);
            for(int i=1;i<=min(n,10);i++)rt(x = rng() % n + 1);
        }
        */
        inline void magic(int &x,char f)
        {
            if(f)
            {
                if(tr[tr[tr[x].ls].ls].size > tr[tr[x].rs].size) rt(x),rt(x);
                else if(tr[tr[tr[x].ls].rs].size > tr[tr[x].rs].size) lt(tr[x].ls),rt(x);
                else return;
            }
            else
            {
                if (tr[tr[tr[x].rs].rs].size > tr[tr[x].ls].size) lt(x);
                else if (tr[tr[tr[x].rs].ls].size > tr[tr[x].ls].size) rt(tr[x].rs),lt(x);
                else return;
            }
            if(rng() & 1)lt(x); //Lucky!
            magic(tr[x].ls,0);magic(tr[x].rs,1);
            return;
        }
        inline void Insert(int &x,int v)
        {
            if (!x)
            {
                x = ++dfn;
                tr[x].ls = tr[x].rs = 0;
                tr[x].size = 1;
                tr[x].val = v;
                //rp();
            }
            else
            {
                tr[x].size++;
                if (v<tr[x].val) Insert(tr[x].ls,v);
                else Insert(tr[x].rs,v);
                magic(x,v < tr[x].val);
            }
        }
        inline int del(int &x,int v)
        {
            tr[x].size--;
            int k = tr[x].val;
            if (v == k || (v < k && !tr[x].ls) || (v > k && !tr[x].rs) )
            {
                if (!tr[x].ls || !tr[x].rs) x = tr[x].ls + tr[x].rs;
                else tr[x].val = del(tr[x].ls,v + 1);
                return k;
            }
            else
            {
                if (v < k) return del(tr[x].ls,v);
                else return del(tr[x].rs,v);
            }
        }
        inline int kth(int k)
        {
            int x = root;
            while(tr[tr[x].ls].size + 1 != k)
            {
                if(tr[tr[x].ls].size+1 < k) k -= tr[tr[x].ls].size,k--,x = tr[x].rs;
                else x = tr[x].ls;
            }
            return tr[x].val;
        }
    }
    using namespace RP;
    int main()
    {
        freopen("xiaoqiao.in","r",stdin);
        freopen("xiaoqiao.out","w",stdout);
        n = read(),m = read(),kk = read();
        for(int i=1;i<=n;i++)
        {
            int R = read(),l = read(),r = read();
            if(l == m) l = -m;
            if(r == -m) r = m;
            if(l == r) continue;
            if(l >= 0 && r >= 0)
            {
                if(l > r)
                {
                    if(m) nega[++top1]=(qwq){-m,0,R};
                    if(l != m) posi[++top2]=(qwq){l,m,R};
                    
                    if(r) posi[++top2]=(qwq){0,r,R};
                }
                else posi[++top2]=(qwq){l,r,R};
            }
            else if(l <= 0 && r <= 0)
            {
                if(l > r)
                {
                    if(l) nega[++top1]=(qwq){l,0,R};
                    if(r != -m) nega[++top1]=(qwq){-m,r,R};
                    
                    if(m) posi[++top2]=(qwq){0,m,R};
                }
                else nega[++top1]=(qwq){l,r,R};
            }
            else if (l <= 0 && r >= 0)
            {
                if (l) nega[++top1]=(qwq){l,0,R};
                if (r) posi[++top2]=(qwq){0,r,R};
            }
            else if(l >= 0 && r <= 0)
            {
                nega[++top1]=(qwq){-m,r,R};
                posi[++top2]=(qwq){l,m,R};
            }
        }
        LL res1 = 0,res2 = 0;
        
        root = dfn = ops = 0;
        for(int i=1;i<=top1;i++)
        {
            opts[++ops] = (ques){nega[i].l,nega[i].R,1};
            opts[++ops] = (ques){nega[i].r,nega[i].R,0};
        }
        sort(opts + 1,opts + ops + 1);
        int last = opts[1].st;
        int l = 1,r = 1;
        while(l <= ops)
        {
            while(r <= ops && opts[r].st == opts[l].st) r++;
            if(tr[root].size >= kk)
            {
                LL x = kth(tr[root].size - kk + 1); //di k da = n - k + 1 xiao
                res1 += x * x * (opts[l].st - last);
            }
            for(int i=l;i<r;i++)
            {
                if(opts[i].f == 1) Insert(root,opts[i].r);
                else del(root,opts[i].r);
            }
            last = opts[l].st;
            l = r;
        }
        
        root = dfn = ops = 0;
        for(int i=1;i<=top2;i++)
        {
            opts[++ops] = (ques){posi[i].l,posi[i].R,1};
            opts[++ops] = (ques){posi[i].r,posi[i].R,0};
        }
        sort(opts + 1,opts + ops + 1);
        last = opts[1].st;
        l = 1,r = 1;
        while(l <= ops)
        {
            while(r <= ops && opts[r].st == opts[l].st) r++;
            if(tr[root].size >= kk)
            {
                LL x = kth(tr[root].size - kk + 1); //di k da = n - k + 1 xiao
                res2 += x * x * (opts[l].st - last);
            }
            for(int i=l;i<r;i++)
            {
                if(opts[i].f == 1) Insert(root,opts[i].r);
                else del(root,opts[i].r);
            }
            last = opts[l].st;
            l = r;
        }
        cout<<res1 + res2;
    }
    T3(xjb转平衡树)
  • 相关阅读:
    SpringBoot发送邮箱验证码
    判断一个数是否为2的整数次幂
    [模板] 虚树 && bzoj2286-[Sdoi2011]消耗战
    [模板] K-D Tree
    [模板] 平衡树: Splay, 非旋Treap, 替罪羊树
    对于约数个数上界的估计
    luogu3702-[SDOI2017]序列计数
    [模板] 线性基
    [模板] 区间mex && 区间元素种数
    bzoj4367-[IOI2014]holiday假期
  • 原文地址:https://www.cnblogs.com/Kong-Ruo/p/9897878.html
Copyright © 2011-2022 走看看