【ContestHunter】【弱省胡策】【Round7】
Prufer序列+高精度+组合数学/DP+可持久化线段树
Magic
利用Prufer序列,我们考虑序列中每个点是第几个插进去的,再考虑环的连接方式,我们有$$ans=\sum_{K=3}^n N^{N-K-1}*K*\frac{(K-1)!}{2} * \binom{N}{K}$$
然而直接高精算会爆……
注意到每一项与前一项相差不大,有$now=last*N/(N-K+1)$,所以我们算出来第一项以后不用每次重算后面的了……
1 //Round7 A 2 #include<cstdio> 3 #include<cstring> 4 #include<cstdlib> 5 #include<iostream> 6 #include<algorithm> 7 #define rep(i,n) for(int i=0;i<n;++i) 8 #define F(i,j,n) for(int i=j;i<=n;++i) 9 #define D(i,j,n) for(int i=j;i>=n;--i) 10 #define pb push_back 11 using namespace std; 12 typedef long long LL; 13 const int N=100010; 14 /*******************template********************/ 15 16 int n; 17 struct bint{ 18 LL v[1500]; 19 int l; 20 LL& operator [] (int x){return v[x];} 21 bint(){l=0; memset(v,0,sizeof v);} 22 }ans; 23 const LL Limit=100000000000000LL; 24 void print(bint& a){ 25 printf("%lld",a[a.l]); 26 D(i,a.l-1,1) printf("%014lld",a[i]); 27 puts(""); 28 } 29 void mul(bint& a,const int &b){ 30 LL tmp=0; 31 F(i,1,a.l){ 32 a[i]=a[i]*b+tmp; 33 tmp=a[i]/Limit; 34 a[i]%=Limit; 35 } 36 if (tmp) a[++a.l]=tmp; 37 } 38 void del(bint& a,const int &b){ 39 LL tmp=0,last=0; 40 D(i,a.l,1){ 41 tmp=(a[i]+last*Limit)%b; 42 a[i]=(a[i]+last*Limit)/b; 43 last=tmp; 44 } 45 while(a[a.l]==0 && a.l) a.l--; 46 } 47 bint operator + (bint a,bint b){ 48 int l=max(a.l,b.l); 49 F(i,1,l){ 50 a[i]+=b[i]; 51 if (a[i]>=Limit) a[i]-=Limit,a[i+1]++; 52 } 53 if (a[l+1]>0) a.l=l+1; else a.l=l; 54 return a; 55 } 56 int main(){ 57 #ifndef ONLINE_JUDGE 58 freopen("A.in","r",stdin); 59 freopen("A.out","w",stdout); 60 #endif 61 scanf("%d",&n); 62 bint p,ans; 63 p[p.l=1]=1; 64 F(i,1,n-2) mul(p,n); 65 mul(p,n-1); 66 del(p,2); 67 F(k,3,n){ 68 mul(p,n-k+1); 69 del(p,n); 70 ans=ans+p; 71 // ans+=Pow(n,n-k-1)*k*fac[k-1]/2*C(n,k); 72 } 73 print(ans); 74 return 0; 75 }
Rectangle
QwQ真是一道好题!
先考虑所有的a[i]=1的情况,这时候我们的做法是线段树维护最大连续区间。
然后我们推广一下,用可持久化线段树,对每一个高度都维护一个最大连续区间。
同时再用一个priority_queue来维护一下当前的答案!(官方题解这里说是set……然而我用set给MLE了!什么鬼!!)
1 //Round7 B 2 #include<cstdio> 3 #include<queue> 4 #include<cstring> 5 #include<cstdlib> 6 #include<iostream> 7 #include<algorithm> 8 #define rep(i,n) for(int i=0;i<n;++i) 9 #define F(i,j,n) for(int i=j;i<=n;++i) 10 #define D(i,j,n) for(int i=j;i>=n;--i) 11 #define pb push_back 12 using namespace std; 13 typedef long long LL; 14 inline LL getint(){ 15 LL r=1,v=0; char ch=getchar(); 16 for(;!isdigit(ch);ch=getchar()) if (ch=='-') r=-1; 17 for(; isdigit(ch);ch=getchar()) v=v*10-'0'+ch; 18 return r*v; 19 } 20 const int N=100001,M=1000001; 21 /*******************template********************/ 22 23 int n,m,Max,a[N],b[N],rt[M],cnt; 24 25 struct node{ 26 int l,r,maxl,maxr,max; 27 }t[10000001]; 28 #define L t[o].l 29 #define R t[o].r 30 #define mid (l+r>>1) 31 #define lch L,l,mid 32 #define rch R,mid+1,r 33 void build(int &o,int l,int r){ 34 o=++cnt; 35 t[o].maxl=t[o].maxr=t[o].max=r-l+1; 36 if (l==r) return; 37 build(lch); 38 build(rch); 39 } 40 inline void maintain(int o,int l,int r){ 41 t[o].maxl=t[L].maxl; t[o].maxr=t[R].maxr; 42 if (t[L].maxl==mid-l+1) t[o].maxl+=t[R].maxl; 43 if (t[R].maxr==r-mid) t[o].maxr+=t[L].maxr; 44 t[o].max=max(t[L].maxr+t[R].maxl,max(t[L].max,t[R].max)); 45 } 46 void update(int &o,int l,int r,int pos){ 47 t[++cnt]=t[o], o=cnt; 48 if (l==r){t[o].maxl=t[o].maxr=t[o].max=0;return;} 49 if (pos<=mid) update(lch,pos); 50 else update(rch,pos); 51 maintain(o,l,r); 52 } 53 bool cmp(int x,int y){return a[x]<a[y];} 54 struct data{ 55 LL v; 56 int id; 57 data(LL x=0,int id=0):v(x),id(id){} 58 bool operator < (const data &b)const{ 59 return v<b.v || (v==b.v && id>b.id); 60 } 61 }; 62 priority_queue<data>Q; 63 int main(){ 64 #ifndef ONLINE_JUDGE 65 freopen("B.in","r",stdin); 66 freopen("B.out","w",stdout); 67 #endif 68 n=getint(); m=getint(); 69 Max=0; 70 F(i,1,n){ 71 a[i]=getint(); 72 Max=max(Max,a[i]); 73 b[i]=i; 74 } 75 sort(b+1,b+n+1,cmp); 76 build(rt[0],1,n); 77 78 LL ans=0; 79 for(int i=1,j=1;i<=Max;i++){ 80 rt[i]=rt[i-1]; 81 for(;a[b[j]]==i-1 && j<=n;j++) 82 update(rt[i],1,n,b[j]); 83 Q.push(data((LL)t[rt[i]].max*i,i)); 84 // printf("height=%d val=%lld\n",i,(LL)t[rt[i]].max*i); 85 } 86 87 data x=Q.top(); 88 printf("%lld\n",ans=x.v); 89 LL pos; 90 while(m--){ 91 pos=getint()^ans; 92 update(rt[a[pos]],1,n,pos); 93 Q.push(data((LL)t[rt[a[pos]]].max*a[pos],a[pos])); 94 a[pos]--; 95 for(x=Q.top(); (LL)x.id*t[rt[x.id]].max!=x.v;Q.pop(),x=Q.top()); 96 ans=Q.top().v; 97 printf("%lld\n",ans); 98 } 99 return 0; 100 }