zoukankan      html  css  js  c++  java
  • 2017 UESTC Training for Data Structures

    2017 UESTC Training for Data Structures

    A    水,找区间极差,RMQ怼上去。

    #include<bits/stdc++.h>
    using namespace std;
    #pragma comment(linker, "/STACK:102400000,102400000")
    #define rep(i,a,b) for (int i=a;i<=b;i++)
    #define per(i,b,a) for (int i=b;i>=a;i--)
    #define mes(a,b)  memset(a,b,sizeof(a))
    #define INF 0x3f3f3f3f
    typedef long long ll;
    const int N = 200005;
    
    int a[N], f1[N][20], f2[N][20];
    void RMQ(int n)
    {
        rep(i,1,n) f1[i][0]=f2[i][0]=a[i];
        rep(j,1,19) rep(i,1,n) {
            if(i+(1<<j)-1<=n) {
                f1[i][j]=max(f1[i][j-1], f1[i+(1<<(j-1))][j-1]);
                f2[i][j]=min(f2[i][j-1], f2[i+(1<<(j-1))][j-1]);
            }
        }
    }
    int main()
    {
        int n, q;
        scanf("%d %d", &n, &q);
            rep(i,1,n) scanf("%d", &a[i]);
            RMQ(n);
            int l, r;
            rep(i,1,q) {
                scanf("%d %d", &l, &r);
                int lg=floor(log10(r-l+1)/log10(2));
                int maxn=max(f1[l][lg], f1[r-(1<<lg)+1][lg]);
                int minn=min(f2[l][lg], f2[r-(1<<lg)+1][lg]);
                printf("%d
    ", maxn-minn);
            }
    
        return 0;
    }
    View Code

    C    线段树区间更新,区间求和。

    题意:N个数排成一列,有三种操作。1.给一段区间内的每个数乘上一个非负整数。2.给一段区间内的每个数加上一个非负整数.3.询问一段区间的和模上P的值。

    tags:由于需要区间加add和区间乘mul,需要维护两个延迟标记。对于add,修改c,则sum+=c*len(区间长度),add+c;对于mul,修改c,则sum*=c;add*=c,mul*=c。乘法分配律(add+sum)*c = add*c+sum*c;

    #include<bits/stdc++.h>
    using namespace std;
    #pragma comment(linker, "/STACK:102400000,102400000")
    #define rep(i,a,b) for (int i=a;i<=b;i++)
    #define per(i,b,a) for (int i=b;i>=a;i--)
    #define mes(a,b)  memset(a,b,sizeof(a))
    #define INF 0x3f3f3f3f
    #define MP make_pair
    #define PB push_back
    #define fi  first
    #define se  second
    typedef long long ll;
    const int N = 100005, M = N<<2;
    
    int n, m;
    ll mod, laz1[M], laz2[M], tr[M];    //laz1[]乘的延迟标记,laz2[]加的延迟标记
    void Init()
    {
        rep(i,0,M-1) laz1[i]=1;
    }
    ll add(ll x, ll y) { return ((x%mod) + (y%mod))%mod; }
    ll mul(ll x, ll y) { return ((x%mod) * (y%mod))%mod; }
    void pushup(int pos)
    {
        tr[pos]=add(tr[pos<<1], tr[pos<<1|1]);
    }
    void build(int pos, int l, int r)
    {
        if(l==r) { scanf("%lld", &tr[pos]); tr[pos]%=mod; return ; }
        int mid=(l+r)>>1;
        build(pos<<1, l, mid);
        build(pos<<1|1, mid+1, r);
        pushup(pos);
    }
    void pushdown(int pos, int len)
    {
        int lson=pos<<1, rson=pos<<1|1;
        tr[lson]= add(mul(tr[lson], laz1[pos]), (laz2[pos]*(len-(len>>1)))%mod);
        tr[rson]= add(mul(tr[rson], laz1[pos]), (laz2[pos]*(len>>1))%mod);
        laz1[lson]= mul(laz1[lson], laz1[pos]);
        laz1[rson]= mul(laz1[rson], laz1[pos]);
        laz2[lson]= add(mul(laz2[lson], laz1[pos]), laz2[pos]);
        laz2[rson]= add(mul(laz2[rson], laz1[pos]), laz2[pos]);
        laz1[pos]=1, laz2[pos]=0;
    }
    void update(int flag, int L, int R, int pos, int l, int r, ll c)
    {
        if(L<=l && r<=R)
        {
            if(flag==1) {
                laz1[pos]=mul(laz1[pos], c);
                laz2[pos]=mul(laz2[pos], c);
                tr[pos]=mul(tr[pos], c);
            } else {
                laz2[pos]=add(laz2[pos], c);
                tr[pos]=add(tr[pos], ((r-l+1)*c)%mod);
            }
            return ;
        }
        pushdown(pos, r-l+1);
        int mid=(l+r)>>1;
        if(L<=mid) update(flag, L, R, pos<<1, l, mid, c);
        if(mid<R)  update(flag, L, R, pos<<1|1, mid+1, r, c);
        pushup(pos);
    }
    ll  query(int L, int R, int pos, int l, int r)
    {
        if(L<=l && r<=R) return tr[pos];
        pushdown(pos, r-l+1);
        int mid=(l+r)>>1;
        ll ans=0;
        if(L<=mid) ans+=query(L, R, pos<<1, l, mid);
        if(mid<R)  ans+=query(L, R, pos<<1|1, mid+1, r);
        pushup(pos);
        return ans%mod;
    }
    int main()
    {
        scanf("%d %lld", &n, &mod);
        Init();
        build(1, 1, n);
        scanf("%d", &m);
        int l, r, flag;   ll c;
        rep(i,1,m)
        {
            scanf("%d %d %d", &flag, &l, &r);
            if(flag!=3) {
                scanf("%lld", &c);
                update(flag, l, r, 1, 1, n, c);
            } else {
                printf("%lld
    ", query(l, r, 1, 1, n));
            }
        }
    
        return 0;
    }
    View Code

    D   水,树状数组

    题意:n个点,每个点的rank值为x坐标不大于其x坐标,且y坐标不大于其y坐标的点的数量。(不含其自身),求出rank为0~n−1的点的数量。

    tags:先对一维坐标排序,然后树状数组维护一下即可。

    // D
    #include<bits/stdc++.h>
    using namespace std;
    #pragma comment(linker, "/STACK:102400000,102400000")
    #define rep(i,a,b) for (int i=a;i<=b;i++)
    #define per(i,b,a) for (int i=b;i>=a;i--)
    #define mes(a,b)  memset(a,b,sizeof(a))
    #define INF 0x3f3f3f3f
    #define fi  first
    #define se  second
    typedef long long ll;
    const int N = 100005;
    
    int n;
    ll  tr[N], ans[N];
    pair<int,int > co[N];
    void add(int x, int y) {for(; x<=n; tr[x]+=y, x+=x&-x); }
    ll sum(int x) {ll ans=0; for(; x>0; ans+=tr[x], x-=x&-x); return ans; }
    int main()
    {
        scanf("%d", &n);
        rep(i,1,n) scanf("%d %d", &co[i].fi, &co[i].se);
        sort(co+1, co+1+n);
        rep(i,1,n)
        {
            ++ans[sum(co[i].se)];
            add(co[i].se, 1);
        }
        rep(i,0,n-1) printf("%lld
    ", ans[i]);
    
        return 0;
    }
    View Code

    E    水,树状数组

    题意:把一个给定的1~n的排列{a1,a2,…,an}(1≤ai≤n,且ai各不相同),用最少的交换次数,变换成另一个1~n的排列{b1,b2,…,bn}。并且,每次只交换相邻的两个元素。求最小的交换次数。

    tags:按b[]的顺序依次计算,直接暴力肯定超时,所以强行搞了个树状数组。。

    #include<bits/stdc++.h>
    using namespace std;
    #pragma comment(linker, "/STACK:102400000,102400000")
    #define rep(i,a,b) for (int i=a;i<=b;i++)
    #define per(i,b,a) for (int i=b;i>=a;i--)
    #define mes(a,b)  memset(a,b,sizeof(a))
    #define INF 0x3f3f3f3f
    typedef long long ll;
    const int N = 100005;
    
    int n, a[N], b[N], id[N], s[N];
    ll ans;
    void add(int x, int c) {for(; x; s[x]+=c, x-=x&-x); }
    int sum(int x) {int ans=0; for(; x<=n; ans+=s[x], x+=x&-x); return ans; }
    int main()
    {
        scanf("%d", &n);
        int cnt=0;
        rep(i,1,n) {
            scanf("%d", &a[i]);
            id[a[i]]=i;
        }
        rep(i,1,n) {
            scanf("%d", &b[i]);
            int id1=id[b[i]], s1=sum(id1);
            ans+= (id1+s1-i);
            add(id1, 1);
        }
        printf("%lld
    ", ans);
    
        return 0;
    }
    View Code

    J    水,优先队列

    #include<bits/stdc++.h>
    using namespace std;
    #pragma comment(linker, "/STACK:102400000,102400000")
    #define rep(i,a,b) for (int i=a;i<=b;i++)
    #define per(i,b,a) for (int i=b;i>=a;i--)
    #define mes(a,b)  memset(a,b,sizeof(a))
    #define INF 0x3f3f3f3f
    typedef long long ll;
    const int N = 200005;
    
    int main()
    {
        int n, ai;
        priority_queue<int , vector<int >, greater<int>  > q;
        scanf("%d", &n);
        rep(i,1,n) {
            scanf("%d", &ai);
            q.push(ai);
        }
        int ans=0;
        rep(i,1,n-1) {
            int x1=q.top(); q.pop();
            int x2=q.top(); q.pop();
            ans+= x1+x2,  q.push(x1+x2);
        }
        printf("%d
    ", ans);
    
        return 0;
    }
    View Code

    L    水,食物链原题

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<algorithm>
    #include<cstring>
    #include<string>
    #include<cmath>
    #include<queue>
    #include<stack>
    #include<map>
    #include<bitset>
    #include<vector>
    #include<set>
    #include<list>
    using namespace std;
    #pragma comment(linker, "/STACK:102400000,102400000")
    #define rep(i,a,b) for (int i=a;i<=b;i++)
    #define per(i,b,a) for (int i=b;i>=a;i--)
    #define mes(a,b)  memset(a,b,sizeof(a))
    #define INF 0x3f3f3f3f
    typedef long long ll;
    const int N = 100005;
    
    int n, k, fa[N*3];
    int ans[N], ans1;
    int Find(int x) {return fa[x]==x ? x : fa[x]=Find(fa[x]); }
    bool same(int a, int b) {return Find(a)==Find(b); }
    void Unite(int a, int b) {
        int faa=Find(a), fab=Find(b);
        if(faa!=fab) fa[faa]=fab;
    }
    int main()
    {
        scanf("%d %d", &n, &k);
        rep(i,1,n*3) fa[i]=i;
        int d, x, y;
        bool flag=0;
        rep(ca, 1, k)
        {
            scanf("%d %d %d", &d, &x, &y);
            if(x>n || y>n) {  ans[++ans1]=ca;  continue; }
            if(d==1)
            {
                if(same(x,y+n) || same(x,y+2*n)) ans[++ans1]=ca;
                else {
                    Unite(x, y); Unite(x+n, y+n); Unite(x+2*n, y+2*n);
                }
            }
            else
            {
                if(x==y || same(x,y) || same(x,y+2*n)) ans[++ans1]=ca;
                else {
                    Unite(x, y+n); Unite(x+n, y+2*n); Unite(x+2*n, y);
                }
            }
        }
        rep(i,1,ans1)
            if(i==1) printf("%d", ans[i]);
            else printf(" %d", ans[i]);
    
        return 0;
    }
    View Code

    M   题目意思太迷

    N   老题了,带正反的并查集

    #include<bits/stdc++.h>
    using namespace std;
    #pragma comment(linker, "/STACK:102400000,102400000")
    #define rep(i,a,b) for (int i=a;i<=b;i++)
    #define per(i,b,a) for (int i=b;i>=a;i--)
    #define mes(a,b)  memset(a,b,sizeof(a))
    #define INF 0x3f3f3f3f
    typedef long long ll;
    const int N = 2000005;
    
    int fa[N];
    int Find(int x) {return fa[x]==x ? x : fa[x]=Find(fa[x]); }
    int main()
    {
        int n, m, t, a, b;
        scanf("%d %d", &n, &m);
        rep(i,1,n*2) fa[i]=i;
        rep(i,1,m) {
            scanf("%d %d %d", &t, &a, &b);
            int faa1=Find(a*2-1), faa2=Find(a*2), fab1=Find(b*2-1), fab2=Find(b*2);
            if(t==1) {
                if(faa1==fab2 || faa2==fab1) {puts("NO"); return 0; }
                fa[faa1]=fab1, fa[faa2]=fab2;
            }
            else {
                if(faa1==fab1 || faa2==fab2) {puts("NO"); return 0; }
                fa[faa1]=fab2, fa[faa2]=fab1;
            }
        }
        puts("YES");
    
        return 0;
    }
    View Code
  • 相关阅读:
    前端性能优化-雅虎军规
    Webpack简易入门教程
    orm框架的使用
    【Nginx】使用nginx反向代理IIS实现80端口的解放
    【开发调试】谷歌浏览器中调试移动网页和测试网速下页面效果
    Identity4实现服务端+api资源控制+客户端请求
    【问题】VS问题集合,不用也要收藏防止以后使用找不到
    【worker】js中的多线程
    pdf.js插件使用记录,在线打开pdf
    【CSS】小妙招,各种问题总结方法处理
  • 原文地址:https://www.cnblogs.com/sbfhy/p/6794205.html
Copyright © 2011-2022 走看看