2019雅礼集训day7 题解

T1 Inverse

2019雅礼集训day7 题解_第1张图片
1 ≤ n ≤ 500 , 0 ≤ k ≤ 50 1\leq n\leq 500,0\leq k\leq 50 1n500,0k50

f ( i , j , k ) f(i,j,k) f(i,j,k)表示 k k k次操作后 P i < P j P_i<P_j Pi<Pj的概率。

考虑暴力 O ( n 4 k ) O(n^4k) O(n4k)的转移:

  • r < i r<i r<i l > j l>j l>j i < l ≤ r < j i<l\leq r<j i<lr<j f ( i , j , k − 1 ) → f ( i , j , k ) f(i,j,k-1)\rightarrow f(i,j,k) f(i,j,k1)f(i,j,k)
  • l ≤ i ≤ r < j l\leq i\leq r<j lir<j f ( l + r − i , j , k − 1 ) → f ( i , j , k ) f(l+r-i,j,k-1)\rightarrow f(i,j,k) f(l+ri,j,k1)f(i,j,k)
  • i < l ≤ j ≤ r i<l\leq j\leq r i<ljr f ( i , l + r − j , k − 1 ) → f ( i , j , k ) f(i,l+r-j,k-1)\rightarrow f(i,j,k) f(i,l+rj,k1)f(i,j,k)
  • l ≤ i < j ≤ r l\leq i< j\leq r li<jr 1 − f ( l + r − j , l + r − i , k − 1 ) → f ( i , j , k ) 1-f(l+r-j,l+r-i,k-1)\rightarrow f(i,j,k) 1f(l+rj,l+ri,k1)f(i,j,k)

前缀和的前缀和将复杂度优化到 O ( n 2 k ) O(n^2k) O(n2k)(为简洁表达,忽略 k k k一维):

  • 对于第二类 l ≤ i ≤ r < j l\leq i\leq r<j lir<j,贡献为
         ∑ l = 1 i ∑ r = i j − 1 f ( l + r − i , j ) \ \ \ \ \sum\limits_{l=1}^i\sum\limits_{r=i}^{j-1}f(l+r-i,j)     l=1ir=ij1f(l+ri,j)
    = ∑ l = 1 i ∑ r = 0 j − i − 1 f ( l + r , j ) =\sum\limits_{l=1}^i\sum\limits_{r=0}^{j-i-1}f(l+r,j) =l=1ir=0ji1f(l+r,j)
    S 1 ( n , j ) = ∑ i = 1 n f ( i , j ) , S 2 ( n , j ) = ∑ i = 1 n S 1 ( i , j ) S_1(n,j)=\sum\limits_{i=1}^nf(i,j),S_2(n,j)=\sum\limits_{i=1}^nS_1(i,j) S1(n,j)=i=1nf(i,j),S2(n,j)=i=1nS1(i,j)

         ∑ l = 1 i ∑ r = 0 j − i − 1 f ( l + r , j ) \ \ \ \ \sum\limits_{l=1}^i\sum\limits_{r=0}^{j-i-1}f(l+r,j)     l=1ir=0ji1f(l+r,j)
    = ∑ l = 1 i S 1 ( l + j − i − 1 , j ) − S 1 ( l − 1 , j ) =\sum\limits_{l=1}^iS_1(l+j-i-1,j)-S_1(l-1,j) =l=1iS1(l+ji1,j)S1(l1,j)
    = S 2 ( j − 1 , j ) − S 2 ( j − i − 1 , j ) − S 2 ( i − 1 , j ) =S_2(j-1,j)-S_2(j-i-1,j)-S_2(i-1,j) =S2(j1,j)S2(ji1,j)S2(i1,j)
  • 对于第三类 i < l ≤ j ≤ r i<l\leq j\leq r i<ljr,贡献为
         ∑ l = i + 1 j ∑ r = j n f ( i , l + r − j ) \ \ \ \ \sum\limits_{l=i+1}^j\sum\limits_{r=j}^{n}f(i,l+r-j)     l=i+1jr=jnf(i,l+rj)
    = ∑ l = i + 1 j ∑ r = 0 n − j f ( i , l + r ) =\sum\limits_{l=i+1}^j\sum\limits_{r=0}^{n-j}f(i,l+r) =l=i+1jr=0njf(i,l+r)
    S 3 ( i , t ) = ∑ j = t n f ( i , j ) , S 4 ( i , t ) = ∑ j = t n S 3 ( i , j ) S_3(i,t)=\sum\limits_{j=t}^nf(i,j),S_4(i,t)=\sum\limits_{j=t}^nS_3(i,j) S3(i,t)=j=tnf(i,j),S4(i,t)=j=tnS3(i,j)

         ∑ l = i + 1 j ∑ r = 0 n − j f ( i , l + r ) \ \ \ \ \sum\limits_{l=i+1}^j\sum\limits_{r=0}^{n-j}f(i,l+r)     l=i+1jr=0njf(i,l+r)
    = ∑ l = i + 1 j S 3 ( i , l ) − S 3 ( i , l + n − j + 1 ) =\sum\limits_{l=i+1}^jS_3(i,l)-S_3(i,l+n-j+1) =l=i+1jS3(i,l)S3(i,l+nj+1)
    = S 4 ( i , i + 1 ) − S 4 ( i , j + 1 ) − S 4 ( i , n + i − j + 2 ) =S_4(i,i+1)-S_4(i,j+1)-S_4(i,n+i-j+2) =S4(i,i+1)S4(i,j+1)S4(i,n+ij+2)
  • 对于第四类 l ≤ i < j ≤ r l\leq i<j\leq r li<jr,贡献为
    i × ( n − j + 1 ) − ∑ l = 1 i ∑ r = j n f ( l + r − j , l + r − i ) i\times(n-j+1)-\sum\limits_{l=1}^i\sum\limits_{r=j}^{n}f(l+r-j,l+r-i) i×(nj+1)l=1ir=jnf(l+rj,l+ri)
    其中
         ∑ l = 1 i ∑ r = j n f ( l + r − j , l + r − i ) \ \ \ \ \sum\limits_{l=1}^i\sum\limits_{r=j}^{n}f(l+r-j,l+r-i)     l=1ir=jnf(l+rj,l+ri)
    = ∑ l = 1 i ∑ r = 0 n − j f ( l + r , l + r + j − i ) =\sum\limits_{l=1}^i\sum\limits_{r=0}^{n-j}f(l+r,l+r+j-i) =l=1ir=0njf(l+r,l+r+ji)
    g ( i , j ) = f ( i , i + j ) g(i,j)=f(i,i+j) g(i,j)=f(i,i+j)

         ∑ l = 1 i ∑ r = 0 n − j f ( l + r , l + r + j − i ) \ \ \ \ \sum\limits_{l=1}^i\sum\limits_{r=0}^{n-j}f(l+r,l+r+j-i)     l=1ir=0njf(l+r,l+r+ji)
    = ∑ l = 1 i ∑ r = 0 n − j g ( l + r , j − i ) =\sum\limits_{l=1}^i\sum\limits_{r=0}^{n-j}g(l+r,j-i) =l=1ir=0njg(l+r,ji)
    S 5 ( n , j ) = ∑ i = 1 n g ( i , j ) , S 6 ( n , j ) = ∑ i = 1 n S 5 ( i , j ) S_5(n,j)=\sum\limits_{i=1}^{n} g(i,j),S_6(n,j)=\sum\limits_{i=1}^nS_5(i,j) S5(n,j)=i=1ng(i,j),S6(n,j)=i=1nS5(i,j)

         ∑ l = 1 i ∑ r = 0 n − j g ( l + r , j − i ) \ \ \ \ \sum\limits_{l=1}^i\sum\limits_{r=0}^{n-j}g(l+r,j-i)     l=1ir=0njg(l+r,ji)
    = ∑ l = 1 i S 5 ( l + n − j , j − i ) − S 5 ( l − 1 , j − i ) =\sum\limits_{l=1}^iS_5(l+n-j,j-i)-S_5(l-1,j-i) =l=1iS5(l+nj,ji)S5(l1,ji)
    = S 6 ( n + i − j , j − i ) − S 6 ( n − j , j − i ) − S 6 ( i − 1 , j − i ) =S_6(n+i-j,j-i)-S_6(n-j,j-i)-S_6(i-1,j-i) =S6(n+ij,ji)S6(nj,ji)S6(i1,ji)

如上维护即可。

#include
#define rep(i,x,y) for(i=x;i<=y;++i)
#define req(i,x,y) for(i=x;i>=y;--i)
#define gc getchar
using namespace std;
typedef long long ll;
typedef double db;
const int N=505,mod=1e9+7;

int n,m,ini[N],f[N][N],ss[N],nv;
int a[N][N],b[N][N],c[N][N];
ll ans;


inline void ad(int &x,int y){x+=y;if(x>=mod) x-=mod;}
inline void dc(int &x,int y){x-=y;if(x<0) x+=mod;}
inline int adi(int x,int y){x+=y;return x>=mod?x-mod:x;}
inline int dci(int x,int y){x-=y;return x<0?x+mod:x;}

char cp,os[100];
template<class T>inline void rd(T &x)
{
	cp=gc();x=0;int f=0;
	for(;!isdigit(cp);cp=gc()) if(cp=='-') f=1;
	for(;isdigit(cp);cp=gc()) x=x*10+(cp^48);
	if(f) x=-x;
}

inline int fp(int x,int y)
{
	int re=1;
	for(;y;y>>=1,x=(ll)x*x%mod) if(y&1) re=(ll)re*x%mod;
	return re;
}

int main(){
	int i,j,k,v;rd(n);rd(m);
	rep(i,1,n) rd(ini[i]),ss[i]=ss[i-1]+i;
	rep(i,1,n) rep(j,i+1,n) f[i][j]=(ini[i]>ini[j]);
	nv=fp(ss[n],mod-2);
	for(;m;--m){
		rep(j,2,n){
			rep(i,1,j-1) a[i][j]=adi(a[i-1][j],f[i][j]);
			rep(i,1,j-1) ad(a[i][j],a[i-1][j]);
		}
		rep(i,1,n){
			req(j,n,i+1) b[i][j]=adi(b[i][j+1],f[i][j]);
			req(j,n,i+1) ad(b[i][j],b[i][j+1]);
		}
		rep(j,0,n){
			rep(i,1,n-j) c[i][j]=adi(c[i-1][j],f[i][i+j]);
			rep(i,1,n-j) ad(c[i][j],c[i-1][j]);
		}
		rep(i,1,n)
		 rep(j,i+1,n){
		 	v=(ll)f[i][j]*(ss[i-1]+ss[j-i-1]+ss[n-j])%mod;
		 	ad(v,dci(a[j-1][j],adi(a[j-i-1][j],a[i-1][j])));
		 	ad(v,dci(b[i][i+1],adi(b[i][j+1],b[i][n+i-j+2])));
		 	dc(v,dci(c[n+i-j][j-i],adi(c[n-j][j-i],c[i-1][j-i])));
		 	ad(v,i*(n-j+1));
		 	f[i][j]=(ll)v*nv%mod;
		 }
	}
	rep(i,1,n) rep(j,i+1,n) ans+=f[i][j];
	printf("%d",ans%mod);
	fclose(stdin);fclose(stdout);
	return 0;
}

T2 Subsequence在这里插入图片描述

n ≤ 1 0 5 , ∣ A i ∣ ≤ 1 0 7 n\leq 10^5,|A_i|\leq 10^7 n105,Ai107

f ( i , j ) f(i,j) f(i,j)表示前 i i i个数选了 j j j个数的最大权值,则
f ( i , j ) = m a x ( f ( i − 1 , j ) , f ( i − 1 , j − 1 ) + j × A i ) f(i,j)=max(f(i-1,j),f(i-1,j-1)+j\times A_i) f(i,j)=max(f(i1,j),f(i1,j1)+j×Ai)

打表/感性/证明发现:对于每一个 i i i,满足 f ( i , j ) f(i,j) f(i,j)最优的 j j j的范围一定是一端以 i i i的后缀。考虑 b s t bst bst维护 d p dp dp值的差分,即 f ( i , j ) − f ( i , j − 1 ) f(i,j)-f(i,j-1) f(i,j)f(i,j1)

每次新加入末端的一个数 a i a_i ai,首先二分找出其在 b s t bst bst上所处位置,然后将后面所有点打上 + a i +a_i +ai标记即可。

#include
#define lc(x) t[x].ch[0]
#define rc(x) t[x].ch[1]
#define F(x) t[x].fa 
using namespace std;
const int N=1e5+10;
typedef long long ll;

int n,a[N],rt,num,stk[N],top;
ll ans[N];

char cp;
inline void rd(int &x)
{
	cp=getchar();x=0;int f=0;
	for(;!isdigit(cp);cp=getchar()) if(cp=='-') f=1;
	for(;isdigit(cp);cp=getchar()) x=x*10+(cp^48);
	if(f) x=-x;
}

struct node{int ch[2],fa,sz;ll g,lzy;}t[N];

inline void pu(int x)
{if(!x) return;t[x].sz=t[lc(x)].sz+t[rc(x)].sz+1;}

inline void dn(int x)
{
	if(!t[x].lzy) return;
	if(lc(x)){
		t[lc(x)].lzy+=t[x].lzy;
		t[lc(x)].g+=t[x].lzy;
	}
	if(rc(x)){
		t[rc(x)].lzy+=t[x].lzy;
		t[rc(x)].g+=t[x].lzy;
	}
	t[x].lzy=0LL;
}

void ins(int fr,int &x,int id,int v,int bs)
{
	if(!x) {x=id;F(x)=fr;t[x].g=(ll)(bs+1)*v;return;}
	dn(x);
	if((ll)(bs+t[lc(x)].sz+1)*v>t[x].g) ins(x,lc(x),id,v,bs);
	else ins(x,rc(x),id,v,bs+t[lc(x)].sz+1);
	pu(x);
}

void dfs(int x)
{
	dn(x);
	if(lc(x)) dfs(lc(x));
	num++;
	ans[num]=t[x].g;
	if(rc(x)) dfs(rc(x));
}

inline void rot(int x)
{
	int y=F(x),z=F(y),dr=(rc(y)==x);
	t[y].ch[dr]=t[x].ch[dr^1];
	if(t[y].ch[dr]) F(t[y].ch[dr])=y;
	F(x)=z;if(z) t[z].ch[rc(z)==y]=x;
	F(y)=x;t[x].ch[dr^1]=y;pu(y);
}

inline void splay(int x)
{
	int y,z;
	for(y=x;y;y=F(y)) stk[++top]=y;
	for(;top;--top) dn(stk[top]);
	for(;F(x);rot(x)){
		y=F(x);z=F(y);
		if(z) ((rc(y)==x)^(rc(z)==y))?rot(x):rot(y);
	}
	rt=x;pu(x);
}

int main(){
	int i,j;rd(n);
	for(i=1;i<=n;++i) rd(a[i]),t[i].sz=1;
	rt=1;t[1].g=a[1];
	for(i=2;i<=n;++i){
		ins(0,rt,i,a[i],0);splay(i);
		if(rc(i)){t[rc(i)].lzy+=a[i];t[rc(i)].g+=a[i];}
	}
	dfs(rt);
	for(i=2;i<=num;++i) ans[i]+=ans[i-1];
	for(i=1;i<=num;++i) printf("%lld ",ans[i]);
	return 0;
}

T3 Convex

2019雅礼集训day7 题解_第2张图片
4 ≤ n ≤ 2 × 1 0 6 , ∣ x i ∣ , ∣ y i ∣ ≤ 1 0 9 4\leq n\leq2\times 10^6,|x_i|,|y_i|\leq 10^9 4n2×106,xi,yi109

两半的面积之差可以转成 ∣ S − 2 X ∣ |S-2X| S2X,其中 S S S为总面积, X X X为其中一半的面积。

枚举对角线,考虑固定对角线的一端,其对踵点前的一段区间均满足 2 X ≤ S 2X\leq S 2XS,后一段均满足 2 X > S 2X>S 2X>S,拆绝对值后转成了求边叉积(相当于一些以原点为端点的三角形的有向面积)的前缀和。再维护一个端点横纵坐标的前缀和,大力讨论即可。

复杂度 O ( n ) O(n) O(n)(线性求对踵点,代码二分求的对踵点( O ( n log ⁡ n ) O(n\log n) O(nlogn)也可过)

#include
using namespace std;
typedef long long ll;
const int N=4e6+10,mod=1e9+7;

int n,ans,dz[N],pz[N],ss;
ll sum,qz[N];

struct P{
	ll x,y;
	P(ll x_=0,ll y_=0):x(x_),y(y_){};
	P operator -(const P&ky){return P(x-ky.x,y-ky.y);}
	P operator +(const P&ky){return P(x+ky.x,y+ky.y);}
}p[N],s[N];

inline ll cg(P a,P b){return a.x*b.y-a.y*b.x;}

inline int fp(int x,int y)
{
	int re=1;
	for(;y;y>>=1,x=(ll)x*x%mod) if(y&1) re=(ll)re*x%mod;
	return re;
}

inline void ad(int &x,int y){x+=y;if(x>=mod) x-=mod;}
inline void dc(int &x,int y){x-=y;if(x<0) x+=mod;}
inline int adi(int x,int y){x+=y;return x>=mod?x-mod:x;}
inline int dci(int x,int y){x-=y;return x<0?x+mod:x;}

inline char gc()
{
	static char buf[1000005];static int p1=0,p2=0;
	if(p1==p2) p1=0,p2=fread(buf,1,1000005,stdin);
	if(p1==p2) return EOF;return buf[p1++];
}

char cp,os[100];
template<class T>inline void rd(T &x)
{
	cp=gc();x=0;int f=0;
	for(;!isdigit(cp);cp=gc()) if(cp=='-') f=1;
	for(;isdigit(cp);cp=gc()) x=x*10+(cp^48);
	if(f) x=-x;
}

template<class T>inline void ot(T x)
{
    if(x<0) putchar('-'),x=-x;
    int re=0;
    for(;(!re)||x;x/=10) os[++re]='0'+x%10;
    for(;re;--re) putchar(os[re]);
}

inline int zlh(ll x){x%=mod;return x<0?x+mod:x;}

inline ll askk(int l,int r){
    if(r<=n) return qz[r]-qz[l-1];
    return sum-(qz[l-1]-qz[r-n]);
}
inline ll gtarea(int l,int r){return askk(l,r-1)+cg(p[l],p[r]);}

inline void sol(int id)
{
	int l=id+2,r=id-2+n,mid,re=id,bs,res,o=0;
	for(;l<=r;){
		mid=(l+r)>>1;
		((gtarea(id,mid))<=(sum>>1))?l=(re=mid)+1:r=mid-1;
	}
    if(re!=id){
    	bs=n-3-((re-id-1)<<1);ad(ans,zlh(-(ll)bs*ss));
    	res=dci(dz[re-1],dz[id]);
    	ad(res,zlh((ll)(bs-1-id)*dci(pz[re-1],pz[id])));
    	ad(res,zlh((ll)bs*dci(pz[id],pz[id-1])));
		ad(o,res);
    	
    	res=dci((ll)zlh(p[id].x)*dci(s[re].y,s[id+1].y)%mod,(ll)zlh(p[id].y)*dci(s[re].x,s[id+1].x)%mod);
    	dc(o,res);
    	
    	if(re<id-2+n){
    	  bs=id-2+n-re;
          res=dci(dz[id-3+n],dz[re-1]);
		  ad(res,zlh((ll)(-re-bs)*dci(pz[id-3+n],pz[re-1])));
		  dc(o,res);
		
		  res=dci((ll)zlh(p[id].x)*dci(s[id-2+n].y,s[re].y)%mod,(ll)zlh(p[id].y)*dci(s[id-2+n].x,s[re].x)%mod);
		  ad(o,res);	
		}
	}else{
		dc(ans,(ll)(n-3)*ss%mod);
		bs=id-2+n;res=dci(dz[bs-1],dz[id]);
		ad(res,zlh((ll)(-n+3-id-1)*dci(pz[bs-1],pz[id])));
		ad(res,zlh((ll)(-n+3)*dci(pz[id],pz[id-1])));
		dc(o,res);
		
		res=dci((ll)zlh(p[id].x)*dci(s[bs].y,s[id+1].y)%mod,(ll)zlh(p[id].y)*dci(s[bs].x,s[id+1].x)%mod);
		ad(o,res);
	}
	ad(ans,adi(o,o));
}

int main(){
	int i;ll res;rd(n);qz[0]=0LL;
	for(i=1;i<=n;++i) rd(p[i].x),rd(p[i].y);
	for(i=2;i<=n;++i) p[i]=p[i]-p[1];p[1]=P(0LL,0LL);
	for(i=1;i<=n;++i) p[i+n]=p[i];
	
	for(i=1;i<=n;++i) qz[i]=qz[i-1]+cg(p[i+1],p[i]);
	for(i=1;i<n+n;++i){
	  s[i]=s[i-1]+p[i];s[i].x=zlh(s[i].x);s[i].y=zlh(s[i].y);
      pz[i]=adi(pz[i-1],zlh(cg(p[i+1],p[i])));
	}
	sum=qz[n];ss=pz[n];
    
	for(i=1;i<n+n;++i) dz[i]=adi(dz[i-1],(ll)i*dci(pz[i],pz[i-1])%mod);
	
	for(i=1;i<=n;++i) sol(i);
	
	printf("%d",(ll)ans*fp(2,mod-2)%mod);
	fclose(stdin);fclose(stdout);
	return 0;
}

小结

T1连dp转移都没想出来,更别说后面的繁琐讨论+求前缀和的前缀和的优化了。
T2比较套路,但还是没有联想到最优决策是一段后缀就上 b s t bst bst
T3很傻,但还是码了很久。

你可能感兴趣的:(凸包,四边形不等式,平衡树,2019YALIWC)