【ContestHunter】【弱省胡策】【Round7】
2015-06-18 21:51
169 查看
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)$,所以我们算出来第一项以后不用每次重算后面的了……
//Round7 B #include<cstdio> #include<queue> #include<cstring> #include<cstdlib> #include<iostream> #include<algorithm> #define rep(i,n) for(int i=0;i<n;++i) #define F(i,j,n) for(int i=j;i<=n;++i) #define D(i,j,n) for(int i=j;i>=n;--i) #define pb push_back using namespace std; typedef long long LL; inline LL getint(){ LL r=1,v=0; char ch=getchar(); for(;!isdigit(ch);ch=getchar()) if (ch=='-') r=-1; for(; isdigit(ch);ch=getchar()) v=v*10-'0'+ch; return r*v; } const int N=100001,M=1000001; /*******************template********************/ int n,m,Max,a ,b ,rt[M],cnt; struct node{ int l,r,maxl,maxr,max; }t[10000001]; #define L t[o].l #define R t[o].r #define mid (l+r>>1) #define lch L,l,mid #define rch R,mid+1,r void build(int &o,int l,int r){ o=++cnt; t[o].maxl=t[o].maxr=t[o].max=r-l+1; if (l==r) return; build(lch); build(rch); } inline void maintain(int o,int l,int r){ t[o].maxl=t[L].maxl; t[o].maxr=t[R].maxr; if (t[L].maxl==mid-l+1) t[o].maxl+=t[R].maxl; if (t[R].maxr==r-mid) t[o].maxr+=t[L].maxr; t[o].max=max(t[L].maxr+t[R].maxl,max(t[L].max,t[R].max)); } void update(int &o,int l,int r,int pos){ t[++cnt]=t[o], o=cnt; if (l==r){t[o].maxl=t[o].maxr=t[o].max=0;return;} if (pos<=mid) update(lch,pos); else update(rch,pos); maintain(o,l,r); } bool cmp(int x,int y){return a[x]<a[y];} struct data{ LL v; int id; data(LL x=0,int id=0):v(x),id(id){} bool operator < (const data &b)const{ return v<b.v || (v==b.v && id>b.id); } }; priority_queue<data>Q; int main(){ #ifndef ONLINE_JUDGE freopen("B.in","r",stdin); freopen("B.out","w",stdout); #endif n=getint(); m=getint(); Max=0; F(i,1,n){ a[i]=getint(); Max=max(Max,a[i]); b[i]=i; } sort(b+1,b+n+1,cmp); build(rt[0],1,n); LL ans=0; for(int i=1,j=1;i<=Max;i++){ rt[i]=rt[i-1]; for(;a[b[j]]==i-1 && j<=n;j++) update(rt[i],1,n,b[j]); Q.push(data((LL)t[rt[i]].max*i,i)); // printf("height=%d val=%lld\n",i,(LL)t[rt[i]].max*i); } data x=Q.top(); printf("%lld\n",ans=x.v); LL pos; while(m--){ pos=getint()^ans; update(rt[a[pos]],1,n,pos); Q.push(data((LL)t[rt[a[pos]]].max*a[pos],a[pos])); a[pos]--; for(x=Q.top(); (LL)x.id*t[rt[x.id]].max!=x.v;Q.pop(),x=Q.top()); ans=Q.top().v; printf("%lld\n",ans); } return 0; }
View Code
相关文章推荐
- 自动化辅助工具Firebug和Firepath的安装
- 《人,绩效和职业道德》及博客读后感
- 使用Canvas绘制图形的基本教程
- 在windows下如何批量转换pvr,ccz为png或jpg
- 得成CMMI大牛
- 冒泡排序与快速排序
- KDE desktop environment
- DAG上的动态规划------硬币问题
- 检查HTTP 的 Digest 认证代码示例-JSP
- 习题3-43
- 【排列组合】bzoj3505 [Cqoi2014]数三角形
- 黑马程序员--异常处理--2nd day
- Java并发编程-27-异常处理及取消任务
- 剑指offer-第四章解决面试题的思路(二叉树的镜像)
- 【枚举】bzoj3391 [Usaco2004 Dec]Tree Cutting网络破坏
- 前端优化-Img与background
- 图算法 专题
- 【半平面交】bzoj2618 [Cqoi2006]凸多边形
- MincostMaxflow
- 学习总结