zoukankan      html  css  js  c++  java
  • 无题十

    今天考崩了,第一题过了大样例就没关了,少考虑了一种情况,直接砍了一半的分,第二题想成了启发式合并,结果后来发现自己实现有问题,搞了很久搞不出来,然后今天就GG了;

    第一题:

    将P按X为第一关键字,将Q按Y为第一关键字排序,我们扫描P确定最小的X,用线段树维护Q做删除,当前删了k个,相当于在Q上查询第m-k+1小的Y;

    此时我们固定了X,说明这个必选选,所以我们要在用此X的Y与线段树查询的Y取min,我就WA在这;

    #include<bits/stdc++.h>
    using namespace std;
    
    const int M = 1e5 + 10;
    int pos[M], n;
    
    struct Mat{
        int x, y, id;
        bool operator < (const Mat &rhs)const {
            if(y == rhs.y) return x < rhs.x;
            return y < rhs.y;
        }
             
    }p[M], q[M];
    
    bool cmp1(Mat a, Mat b){
        return a.x == b.x ? a.y < b.y : a.x < b.x;
    }
    bool cmp2(Mat a, Mat b){
        if(a.y == b.y) return a.x < b.x;
        return a.y > a.y;
    }
    struct Node{
        Node *ls, *rs;
        int sum;
        void up(){
            sum = ls->sum + rs->sum;
        }
    }pool[M<<2], *root, *tail=pool; 
    Node *build(int lf=1,int rg=n){
        Node *nd =++tail;
        if(lf==rg)nd->sum = 1;
        else {
            int mid=(lf+rg)>>1;
            nd->ls=build(lf,mid);
            nd->rs=build(mid+1,rg);
            nd->up();
        }
        return nd;
    }
    #define Ls lf,mid,nd->ls
    #define Rs mid+1,rg,nd->rs
    void modify(int pos, int d, int lf=1,int rg=n,Node *nd = root){
        if(lf == rg) nd->sum += d;
        else {
            int mid=(lf+rg)>>1;
            if(pos<=mid)modify(pos,d, Ls);
            else modify(pos,d, Rs);
            nd->up();
        }
    }
    int query(int k, int lf=1,int rg=n,Node *nd=root){
        if(lf==rg)return lf;
        else {
            int mid=(lf+rg)>>1;
            if(nd->ls->sum >= k) return query(k, Ls);
            return query(k - nd->ls->sum, Rs);
        }
    }
    int read(){
        int x=0,f=1;char c=getchar();
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
        return x*=f;
    }
    
    int main(){
        freopen("d.in","r",stdin);
        freopen("d.out","w",stdout);
        int T;
        scanf("%d", &T);
        while(T--){
            tail = pool;
            int m;
            
            n = read(); m = read();
            for(int i = 1; i <= n; i++){
                p[i].x = read(), p[i].y = read(), p[i].id = i;
                q[i] = p[i];
            }
            sort(q + 1, q + 1 + n);//2 y
            //for(int i=1;i<=n;i++)printf("%d ",q[i].y );
            for(int i = 1; i <= n; i++) {
                pos[q[i].id] = i;
            }    
            root = build();
            sort(p + 1, p + 1 + n, cmp1);//1 x
            int now , cnt = 0;
            long long lst = p[1].x;
            long long ret = 1LL*p[1].x*q[query(m+1)].y;
            for(int i = 1; i <= m; i++){
                modify(pos[p[i].id], -1);
                now = query(m - i + 1);
                lst = p[i+1].x;
                long long ans = lst * 1LL*min(q[now].y, p[i+1].y);
                
                //printf("%lld %d
    ", lst, q[now].y);
                ret = max(ans, ret);
                
            }
            printf("%lld
    ", ret);
            
        }
    }
    View Code

    第二题:

    #include<bits/stdc++.h>
    using namespace std;
    const int M = 1e5 + 5, MN = 3e5 + 5;
    int anc[M][22], p[MN], a[M], tot, h[M], lson[MN * 40], sum[MN * 40], rson[MN * 40]; 
    int root[M], inf = 1e9, P = 20, tail, dep[M];
    struct edge{int v, nxt;}G[M<<1];
    void add(int u, int v){
        G[++tot].v=v,G[tot].nxt=h[u],h[u]=tot;
    }
    void up(int rt){
        sum[rt] = sum[lson[rt]] + sum[rson[rt]];
    }
    
    #define Ls lson[nd], lf, mid
    #define Rs rson[nd], mid + 1, rg
    int insert(int v, int nd, int lf = 1, int rg = inf){
        int rt = ++tail;
        sum[rt] = sum[nd] + 1;
        if(lf == rg);
        else {
            int mid = (lf + rg) >> 1;
            if(v <= mid){
                rson[rt] = rson[nd];
                lson[rt] = insert(v, Ls);
            }
            else {
                lson[rt] = lson[nd];
                rson[rt] = insert(v, Rs);
            }
            up(rt);
        }
        return rt;
    }
    int query1(int v, int nnd, int nd, int lf = 1, int rg = inf){
        if(sum[nnd] == sum[nd]) return 0;
        if(lf == rg) return lf;
        int mid = (lf + rg) >> 1;
        if(mid >= v) return query1(v, lson[nnd], Ls);
        int tmp = 0;
        tmp = query1(v, rson[nnd], Rs);
        if(!tmp) tmp = query1(v, lson[nnd], Ls);
        return tmp;
    }
    
    int query2(int v, int nnd, int nd, int lf = 1, int rg = inf){
        if(sum[nnd] == sum[nd]) return 0;
        if(lf == rg) return lf;
        int mid = (lf + rg) >> 1;
        if(mid < v) return query2(v, rson[nnd], Rs);
        int tmp = 0;
        tmp = query2(v, lson[nnd], Ls);
        if(!tmp) tmp = query2(v, rson[nnd], Rs);
        return tmp;
    }
    
    void dfs(int u, int f){
        anc[u][0] = f;
        for(int p = 1; p <= P; p++)
            anc[u][p] = anc[anc[u][p-1]][p-1];
        dep[u] = dep[f] + 1;
        root[u] = insert(a[u], root[f]);
        for(int i = h[u]; i; i = G[i].nxt){
            int v = G[i].v;
            if(v == f)continue;
            dfs(v, u);
        }
    }
    int lca(int u, int v){
        if(dep[u] < dep[v]) swap(u, v);
        int t = dep[u] - dep[v];
        for(int p = 0; t; t>>=1, p++)
            if(t&1) u = anc[u][p];
        if(u == v) return u;
        for(int p = P; p >= 0; p--)
            if(anc[u][p] != anc[v][p])
                u = anc[u][p], v = anc[v][p];
        return anc[u][0];    
    }
    
    int read(){
        int x=0,f=1;char c=getchar();
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
        return x*=f;
    }
    
    int main(){
        freopen("e.in","r",stdin);
        freopen("e.out","w",stdout);
        int n, Q, t, u, v, r, k;
        scanf("%d%d%d", &n, &Q, &t);
        for(int i = 1; i <= n; i++) a[i] = read();
        for(int i = 1; i < n; i++){
            u = read(), v = read();
            add(u, v); add(v, u);
        }    
        dfs(1, 0);
        int lst = 0;
        root[0] = ++tail;
        while(Q--){
            r = read(); k = read();
            for(int i = 1; i <= k; i++) p[i] = read();
            p[1] = (p[1] - 1 + lst*t) % n + 1;
            int f = p[1];
            for(int i = 2; i <= k; i++){
                p[i] = (p[i] - 1 + lst*t) % n + 1;
                f = lca(f, p[i]);
            } 
            f = anc[f][0];
            int res = 2e9;
            for(int i = 1; i <= k; i++){
                int a1 = query1(r, root[f], root[p[i]]);
                int a2 = query2(r, root[f], root[p[i]]);
                if(a1 && r - a1 < res) res = r - a1;
                if(a2 && a2 - r < res) res = a2 - r;
            //    printf("%d %d/////
    ",a1, a2);
            }
            lst = res;
            printf("%d
    ", lst);
        }    
        
    }
    View Code

    第三题:(我不想管了)

    以下是std

    #include<bits/stdc++.h>
    using namespace std;
    
    typedef long long ll;
    const int maxn=5e5+10,maxk=30+5;
    int n,k,p,a[maxn],k1,k2;
    ll val0[maxk],val1[maxk];
    vector<int> vec;
    vector<pair<ll,int> > vec1,vec2;
    
    void init(vector<int>&vec,int k){
        if(k<0||vec.empty())
            return;
        int cnt0=0,cnt1=0;
        vector<int> vec0,vec1;
        for(int i=0;i<vec.size();++i)
            if(vec[i]>>k&1){
                ++cnt1;
                val1[k]+=cnt0;
                vec1.push_back(vec[i]);
            }
            else{
                ++cnt0;
                val0[k]+=cnt1;
                vec0.push_back(vec[i]);
            }
        init(vec0,k-1);
        init(vec1,k-1);
    }
    inline int calc(pair<ll,int> limit){
        int res=0;
        for(int i=0,j=vec2.size()-1;i<vec1.size();++i){
            while(~j&&make_pair(vec1[i].first+vec2[j].first,vec1[i].second|vec2[j].second<<k1)>limit)
                --j;
            res+=j+1;
        }
        return res;
    }
    
    int main(){
        freopen("f.in","r",stdin);
        freopen("f.out","w",stdout);
        scanf("%d%d%d",&n,&k,&p);
        for(int i=0;i<n;++i)
            scanf("%d",&a[i]);
        vec=vector<int>(a,a+n);
        init(vec,k-1);
        k1=k/2;k2=k-k1;
        for(int i=0;i<1<<k1;++i){
            ll tmp=0;
            for(int j=0;j<k1;++j)
                if(i>>j&1)
                    tmp+=val1[j];
                else
                    tmp+=val0[j];
            vec1.push_back(make_pair(tmp,i));
        }
        sort(vec1.begin(),vec1.end());
        for(int i=0;i<1<<k2;++i){
            ll tmp=0;
            for(int j=0;j<k2;++j)
                if(i>>j&1)
                    tmp+=val1[k1+j];
                else
                    tmp+=val0[k1+j];
            vec2.push_back(make_pair(tmp,i));
        }
        sort(vec2.begin(),vec2.end());
        ll l1=0,r1=n*(n-1ll)/2;
        while(l1<r1){
            ll mid=(l1+r1)/2;
            if(calc(make_pair(mid,1<<k))<p)
                l1=mid+1;
            else
                r1=mid;
        }
        int l2=0,r2=(1<<k)-1;
        while(l2<r2){
            int mid=(l2+r2)/2;
            if(calc(make_pair(l1,mid))<p)
                l2=mid+1;
            else
                r2=mid;
        }
        printf("%lld %d
    ",l1,l2);
        return 0;
    }
    View Code
  • 相关阅读:
    LeetCode 38. 外观数列
    LeetCode 33. 搜索旋转排序数组
    LeetCode 31. 下一个排列
    LeetCode 34. 在排序数组中查找元素的第一个和最后一个位置
    LeetCode 29. 两数相除
    LeetCode 22. 括号生成
    LeetCode 1. 两数之和
    LeetCode 17. 电话号码的字母组合
    LeetCode 18. 四数之和
    LeetCode 16. 最接近的三数之和
  • 原文地址:https://www.cnblogs.com/EdSheeran/p/9767934.html
Copyright © 2011-2022 走看看