20190803考试反思
这次考试就不骂自己了,毕竟骂了也没用。T1是水题。。用map手卡30分,我tm。。。。然后以为这就结束了,然后去改T2,T2WA40,我写的主席树但是修改是自己yy的,以为就是错了,然后把离散化去了,WA80?????!!!然后加上WA40。。。。然后我好好研究了一下,突然想到它可能询问从没出现过的颜色,然后判了一句,A了。。。。因为没出现过就是0,主席树查不出来。。。T3考场上吃屎一会再说。
T1:这是一道规律题,找的话其实打个父亲表,看一下就能知道,一个数的父亲就是这个数之前减去离他最近的斐波数,我们又可以知道这个斐波数增长飞快,见过通项的都知道,这玩意是指数级的,所以就可以打个表知道大概60多个就到13位了,找父亲log60,抬lca是60,一次操作就是常数,m次绝对可以接受,结果忘了之前搞得一个map没删,就死了30分。
#include<iostream> #include<cstdio> #include<algorithm> #include<map> using namespace std; long long f[10000]; long long rd() { long long s=0,w=1; char cc=getchar(); while(cc<'0'||cc>'9') {if(cc=='-') w=-1;cc=getchar();} while(cc>='0'&&cc<='9') s=(s<<3)+(s<<1)+cc-'0',cc=getchar(); return s*w; } long long fa(long long x) { long long id=lower_bound(f+1,f+64,x)-f-1; return x-f[id]; } long long getdep(long long tmp) { long long ans=0,x=tmp; while(x!=1) { ++ans; x=fa(x); } return ans; } long long lca(long long a,long long b) { int depa=getdep(a),depb=getdep(b); if(depa<depb) swap(a,b),swap(depa,depb); while(depa>depb) a=fa(a),depa--; if(a==b) return a; while(fa(a)!=fa(b)) a=fa(a),b=fa(b); return fa(a); } int main() { f[0]=1;f[1]=1; for(int i=2;i<=63;i++) { f[i]=f[i-1]+f[i-2]; } int m=rd(); for(int i=1;i<=m;i++) { long long a=rd(),b=rd(); if(a==1||b==1) { puts("1"); continue; } printf("%lld ",lca(a,b)); } return 0; } /* g++ 1.cpp -o 1 ./1 5 1 1 2 3 5 7 7 13 4 12 */
T2:手动修改的主席树,因为这个修改不是修改,是交换,这很重要,那这样后面的主席树都不用改,只改一颗就行了,然后就可以性感询问,在线回复了。还是一样,可持久化烧内存,内存开够就没了。主席树码量极小
#include<iostream> #include<cstdio> using namespace std; const int N=300050; int rt[N],a[N],p[N],tt=0,cnt=0; struct tree{int lc,rc,w;}tr[50000020]; int rd() { int s=0,w=1; char cc=getchar(); while(cc<'0'||cc>'9') {if(cc=='-') w=-1;cc=getchar();} while(cc>='0'&&cc<='9') s=(s<<3)+(s<<1)+cc-'0',cc=getchar(); return s*w; } void insert(int &x,int l,int r,int p,int va) { tr[++tt]=tr[x];x=tt; if(l==r) { tr[x].w+=va; return; } int mid=(l+r)>>1; if(p<=mid) insert(tr[x].lc,l,mid,p,va); else insert(tr[x].rc,mid+1,r,p,va); } int query(int x,int l,int r,int p) { if(l==r)return tr[x].w; int mid=(l+r)>>1; if(p<=mid)return query(tr[x].lc,l,mid,p); else return query(tr[x].rc,mid+1,r,p); } int main() { int n=rd(),m=rd(); for(int i=1;i<=n;i++) { a[i]=rd(); if(!p[a[i]]) p[a[i]]=++cnt; } for(int i=1;i<=n;i++) { rt[i]=rt[i-1]; insert(rt[i],1,cnt,p[a[i]],1); } while(m--) { int op=rd(); if(op==1) { int l=rd(),r=rd(),c=rd(); if(!p[c]) puts("0"); else printf("%d ",query(rt[r],1,cnt,p[c])-query(rt[l-1],1,cnt,p[c])); } else { int l=rd(); insert(rt[l],1,cnt,p[a[l]],-1); insert(rt[l],1,cnt,p[a[l+1]],1); swap(a[l],a[l+1]); } } } /* g++ 2.cpp -o 2 ./2 10 9 1 2 3 4 5 6 1 2 3 4 1 1 3 3 1 4 6 3 2 3 1 1 3 3 1 4 6 3 1 1 10 4 1 1 10 3 1 1 10 2 1 1 10 1 */