今天考崩了,第一题过了大样例就没关了,少考虑了一种情况,直接砍了一半的分,第二题想成了启发式合并,结果后来发现自己实现有问题,搞了很久搞不出来,然后今天就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); } }
第二题:
#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); } }
第三题:(我不想管了)
以下是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; }