无题十

 

 

今天考崩了,第一题过了大样例就没关了,少考虑了一种情况,直接砍了一半的分,第二题想成了启发式合并,结果后来发现自己实现有问题,搞了很久搞不出来,然后今天就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\n", lst, q[now].y);
            ret = max(ans, ret);
            
        }
        printf("%lld\n", 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/\n",a1, a2);
        }
        lst = res;
        printf("%d\n", 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\n",l1,l2);
    return 0;
}
View Code

 

转载于:https://www.cnblogs.com/EdSheeran/p/9767934.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值