好气啊,本来以为比赛时间还有很多,结果回家养病两天回到学校怎么比赛就结束了(雾),大约是小高考弄错了时间?
挑3道有意思的写写题解吧。
Cloning
题目大意:给一个序列,每次询问两个等长区间,问区间内的数是否排序后至多只有一个对应位不同。
题解:主席树维护一下hash,求出最大的k,使得两个区间中的前k大在排序后相同,然后判一下后缀即可。
#include<cstdio> #include<algorithm> #define MN 110000 #define ull unsigned long long using namespace std; int read_p,read_ca; inline int read(){ read_p=0;read_ca=getchar(); while(read_ca<'0'||read_ca>'9') read_ca=getchar(); while(read_ca>='0'&&read_ca<='9') read_p=read_p*10+read_ca-48,read_ca=getchar(); return read_p; } const ull base=2636363; int T,n,m,ro[MN],num=0,a,b,c,d; ull H[MN]; struct na{int l,r,s;ull h;na(){s=h=0;}}t[MN*20]; inline void add(int &p,int x,int l,int r,int k){ p=++num;t[p]=t[x]; t[p].h+=H[k];t[p].s++; if (l==r) return; int mid=l+r>>1; if (k<=mid) add(t[p].l,t[x].l,l,mid,k);else add(t[p].r,t[x].r,mid+1,r,k); } inline int aski(int a,int b,int c,int d,int l,int r){ if (t[b].h-t[a].h==t[d].h-t[c].h&&t[b].s-t[a].s==t[d].s-t[c].s) return t[b].s-t[a].s; if (l==r) return min(t[b].s-t[a].s,t[d].s-t[c].s); int mid=l+r>>1; int mmh=aski(t[a].l,t[b].l,t[c].l,t[d].l,l,mid); if (mmh==t[t[b].l].s-t[t[a].l].s&&mmh==t[t[d].l].s-t[t[c].l].s) mmh+=aski(t[a].r,t[b].r,t[c].r,t[d].r,mid+1,r); return mmh; } inline int aska(int a,int b,int c,int d,int l,int r){ if (t[b].h-t[a].h==t[d].h-t[c].h&&t[b].s-t[a].s==t[d].s-t[c].s) return t[b].s-t[a].s; if (l==r) return min(t[b].s-t[a].s,t[d].s-t[c].s); int mid=l+r>>1; int mmh=aska(t[a].r,t[b].r,t[c].r,t[d].r,mid+1,r); if (mmh==t[t[b].r].s-t[t[a].r].s&&mmh==t[t[d].r].s-t[t[c].r].s) mmh+=aska(t[a].l,t[b].l,t[c].l,t[d].l,l,mid); return mmh; } int main(){ int i; T=read(); H[1]=1; for (i=2;i<=1e5;i++) H[i]=H[i-1]*base; while(T--){ n=read();m=read();num=0; for (i=1;i<=n;i++) add(ro[i],ro[i-1],1,1e5,read()); while(m--){ a=read();b=read();c=read();d=read(); puts(aska(ro[a-1],ro[b],ro[c-1],ro[d],1,1e5)+aski(ro[a-1],ro[b],ro[c-1],ro[d],1,1e5)>=b-a?"YES":"NO"); } } }
Euler Sum
题目大意:求$sum_{1}^{n}leftlfloor i*e ight floor$
题解:连分数求出e的近似分数以后类欧即可
z,m=1,0 def work(x): global z,m z,m=m,z z+=m*x def mmh(n,z,m): if n==0 or z==0 or m==0: return 0 p=int(z//m) z-=int(p*m) N=int(n*z//m) return n*(n+1)//2*p+int(n*N)-int(mmh(N,m,z)) i=3000 while (i>0): work(i*2) work(1) work(1) i-=1 z+=m n=int(input()) mmh=0 f=1 while(n>0): p=z//m z-=p*m N=n*z//m mmh+=f*(n*(n+1)//2*p+n*N) f*=-1 n=N z,m=m,z print(mmh)
Persistent oak
题意:不想写啊
题解:链剖后可持久化线段树即可,注意打标记,下放标记的时候都要新建节点,不然会影响到历史版本。
#include<cassert> #include<cstdio> #include<cstring> #include<algorithm> #define MN 210000 #define lp t[p].l #define rp t[p].r using namespace std; int read_p,read_ca; inline int read(){ read_p=0;read_ca=getchar(); while(read_ca<'0'||read_ca>'9') read_ca=getchar(); while(read_ca>='0'&&read_ca<='9') read_p=read_p*10+read_ca-48,read_ca=getchar(); return read_p; } struct na{int y,ne;}b[MN<<1]; struct tree{int l,r,M,m,d;bool re;}t[MN*200]; int T,n,m,ty,l[MN],fa[MN],si[MN],de[MN],son[MN],to[MN],x,y,w[MN],df[MN],pdf[MN],lo[MN],ro[MN],nm,NUM,num; char s[10]; inline void in(int x,int y){b[++num].y=y;b[num].ne=l[x];l[x]=num;} inline int min(int a,int b){return a<b?a:b;} void dfs(int x){ si[x]=1;son[x]=0; for (int i=l[x];i;i=b[i].ne) if (fa[b[i].y]=x,de[b[i].y]=de[x]+1,dfs(b[i].y),si[x]+=si[b[i].y],si[son[x]]<si[b[i].y]) son[x]=b[i].y; } void DFS(int x,int p){ to[x]=p;df[x]=++nm;pdf[nm]=x; if (son[x]) DFS(son[x],p); for (int i=l[x];i;i=b[i].ne) if (b[i].y!=son[x]) DFS(b[i].y,b[i].y); lo[x]=nm; } inline void hb(int &p,int d,bool bo=0){ if (!p) return; t[++NUM]=t[p];p=NUM; if (bo) t[p].re=1,t[p].m=t[p].M,t[p].d=0;else t[p].m+=d,t[p].d+=d,assert(t[p].m<=t[p].M); } inline void pd(int &p){ t[++NUM]=t[p];p=NUM; if (t[p].re) hb(lp,0,1),hb(rp,0,1),t[p].re=0; if (t[p].d) hb(lp,t[p].d),hb(rp,t[p].d),t[p].d=0; } inline void gx(int &p){ t[p].m=min(t[lp].m,t[rp].m); t[p].M=min(t[lp].M,t[rp].M); } void build(int &p,int l,int r){ p=++NUM;t[p].l=t[p].r=t[p].d=t[p].re=0; if (l==r){ t[p].M=t[p].m=w[pdf[l]]; return; } int mid=l+r>>1; build(t[p].l,l,mid);build(t[p].r,mid+1,r); gx(p); } void add(int &p,int x,int l,int r,int L,int R,int d){ p=++NUM;t[p]=t[x]; pd(p);x=p; if (L==l&&R==r) hb(p,d);else{ int mid=l+r>>1; if (R<=mid) add(lp,t[x].l,l,mid,L,R,d);else if (L>mid) add(rp,t[x].r,mid+1,r,L,R,d);else add(lp,t[x].l,l,mid,L,mid,d),add(rp,t[x].r,mid+1,r,mid+1,R,d); gx(p); } } int ask(int &p,int l,int r,int k){ pd(p); if (l==r) return t[p].m; int mid=l+r>>1; if (k<=mid) return ask(lp,l,mid,k);else return ask(rp,mid+1,r,k); } int mask(int &p,int l,int r,int L,int R){ pd(p); if (t[p].m>=0) return -1; if (l==r) return pdf[l]; int mid=l+r>>1,s; if (R<=mid) return mask(lp,l,mid,L,R);else if (L>mid) return mask(rp,mid+1,r,L,R);else if (s=mask(rp,mid+1,r,mid+1,R),s!=-1) return s;else return mask(lp,l,mid,L,mid); } inline void reset(int &p,int x,int l,int r,int L,int R){ p=++NUM;t[p]=t[x]; pd(p);x=p; if (L==l&&R==r) hb(p,0,1);else{ int mid=l+r>>1; if (R<=mid) reset(lp,t[x].l,l,mid,L,R);else if (L>mid) reset(rp,t[x].r,mid+1,r,L,R);else reset(lp,t[x].l,l,mid,L,mid),reset(rp,t[x].r,mid+1,r,mid+1,R); gx(p); } } inline void dec(int &p,int x,int u,int d){ while (u){ add(p,x,1,n,df[to[u]],df[u],d);x=p; u=fa[to[u]]; } } inline void work(int &p,int x,int y,int d){ int u=y,s=-1; while (u){ add(p,x,1,n,df[to[u]],df[u],-d);x=p; if (s==-1) s=mask(p,1,n,df[to[u]],df[u]); u=fa[to[u]]; } if (s!=-1){ printf("%d ",s-1); y=w[s]-ask(p,1,n,df[s]); reset(p,p,1,n,df[s],lo[s]); dec(p,p,fa[s],y); }else puts("0"); } int main(){ int i; T=read(); while (T--){ n=read();m=read();n++;w[1]=1e9;NUM=num=nm=0; memset(ro,0,sizeof(ro));memset(l,0,sizeof(l)); for (i=2;i<=n;i++) in(read()+1,i),w[i]=read(); dfs(1);DFS(1,1);build(ro[0],1,n); for (i=1;i<=m;i++){ x=read();ty=read(); if (ty==1){ y=read()+1; work(ro[i],ro[x],y,read()); }else{ y=read()+1; printf("%d ",ty=(w[y]-ask(ro[x],1,n,df[y]))); reset(ro[i],ro[x],1,n,df[y],lo[y]); dec(ro[i],ro[i],fa[y],ty); } } } }