zoukankan      html  css  js  c++  java
  • 【ContestHunter】【弱省胡策】【Round7】

    Prufer序列+高精度+组合数学/DP+可持久化线段树


    Magic

      利用Prufer序列,我们考虑序列中每个点是第几个插进去的,再考虑环的连接方式,我们有$$ans=sum_{K=3}^n N^{N-K-1}*K*frac{(K-1)!}{2} * inom{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 }
    View Code

    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
    ",i,(LL)t[rt[i]].max*i);
     85     }
     86 
     87     data x=Q.top();
     88     printf("%lld
    ",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
    ",ans);
     98     }
     99     return 0;
    100 }
    View Code
  • 相关阅读:
    异常练习一 throw
    MAP排序
    Java正则表达式应用详解
    java多线程 sleep()和wait()的区别
    面向对象的15、18位中国大陆身份证号码解析、工具
    java学习笔记--this 关键字的理解
    Java六大问题你都懂了吗?
    Java类的声明和访问介绍
    java的五种数据类型解析
    Java集合框架的总结
  • 原文地址:https://www.cnblogs.com/Tunix/p/4587162.html
Copyright © 2011-2022 走看看