2018HNCCPC(Onsite)
Time:
Link
A
赛时AC
B
题意
分析
猜结论题
C
题意
分析
可持久化线段树
my solution:二分位置后在主席树上求和check,时间复杂度(n+m)*(logn*logn)
std:时间复杂度(n+m)*logn
#include<stdio.h> #include<bits/stdc++.h> #include<vector> #include<algorithm> #include<cmath> using namespace std; const int maxn = 1e5+7; int n,q,l,r,a[maxn],root[maxn],cnt; struct node{ int l,r,sum; }t[maxn*40]; void update(int l,int r,int &x,int y,int pos) { t[++cnt]=t[y],t[cnt].sum++,x=cnt; if(l==r) return; int mid=(l+r)/2; if(pos<=mid) update(l,mid,t[x].l,t[y].l,pos); else update(mid+1,r,t[x].r,t[y].r,pos); } int query(int l,int r,int x,int y,int pos) { if(pos<=l) return t[y].sum-t[x].sum; int mid=(l+r)/2; int sum=0; if(pos<=mid) { sum+=query(l ,mid, t[x].l, t[y].l, pos); sum+=query(mid+1, r, t[x].r, t[y].r, pos); } else sum+=query(mid+1,r,t[x].r,t[y].r,pos); return sum; } int main() { while(scanf("%d%d",&n,&q)!=EOF) { for(int i=1;i<=n;i++) t[i].sum=0; for(int i=1;i<=n;i++) scanf("%d",&a[i]),update(1,n,root[i],root[i-1],a[i]); while(q--) { scanf("%d%d",&l,&r); int ql=1,qr=n; while(ql<qr) { int mid=(ql+qr+1)/2; if(query(1,n,root[l-1],root[r],mid) >= mid) ql=mid; else qr=mid-1; } printf("%d\n",ql); } } return 0; }
D
题意
分析
E
题意
分析
F
分析
结构体排序即可
G
分析
考虑以每个c为分界点,两个串a,b数量的奇偶性相同即可
H
题意
分析
I
题意
分析
J
题意
n个结点的完全图,每个图有一个权重wi,现给出n,k,k用二进制表示那些点已经被选了,问你有多少个边的子集为k,一条边的两个端点被选了就可以表示这条边被选了(n<1e5)
分析
从大到小考虑每个1(也就是被选的结点),考虑它被选了,那么它一定与他前面的0有边,后面的0可有可无,最后对于每个1来说,它们之间的边都是可有可无,乘上2^(1的数量)即可,注意取mod
K
题意
分析
Reply
前期和其他队伍一样,试图做A,但题意没弄明白了,这时yxl和czh开了k并上机,搞了半天发现有问题,ym则迅速开了F,并2A,稳住了局面,yxl不久也搞出来K,后ym和czh继续去想(猜)A的题意,一次次失望,终于czh最后猜出了正确的题意,yxl也A掉了G,4题后,最终看出C要用主席树,但我们三个都没写过,剩下一个小时四十分钟等死
Summary
Ym:
Czh: