您的位置:首页 > 其它

【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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: