• 9.1 正睿提高2



    2018.9.1 Test

    时间:3.5h
    实际得分:40+50+20

    比赛链接

    T1直接忽略了,刚了3小时T2(暴力写法不好,直接乘逆元就行→_→),算是有点成果吧。。
    然后20分钟写完T1、T3。感觉T3也算可做的。

    A(凸壳 单调栈)

    题目链接

    注意到(c_i=0),即二次函数对称轴都为y轴,但是好像还是很难做。。
    但是这样我们可以把一个x提出来,变成(x(ax+b))
    所以(x>0)时,我们要求(max{a_i*x+b_i}),即维护一个上凸壳;(x<0)时,维护一个下凸壳。
    求法都一样,还是对斜率排序,用单调栈维护。更新时看i,sk[top],sk[top-1]间的关系。
    求出凸壳后,可以在这些直线中二分出最大最小值是哪条直线。可以将求min时的直线乘-1,询问时再取反,就可以只写一个Find_Max的二分了(随意)。

    还是用上/下凸壳指直线斜率递增/递减吧(凸函数)。。和图形反着。

    只求了个上凸壳,在上面二分最小值直线是。。是错的。

    #include <cstdio>
    #include <cctype>
    #include <algorithm>
    //#define gc() getchar()
    #define MAXIN 300000
    #define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++)
    typedef long long LL;
    const int N=5e5+5;
    
    int n;
    LL ans[32330*2];
    char IN[MAXIN],*SS=IN,*TT=IN;
    struct Line
    {
    	int k,b;
    	Line() {}
    	Line(int k,int b):k(k),b(b) {}
    	bool operator <(const Line &x)const{
    		return k==x.k?b>x.b:k<x.k;
    	}
    }lu[N],ld[N],cu[N],cd[N];
    
    inline int read()
    {
    	int now=0,f=1;register char c=gc();
    	for(;!isdigit(c);c=='-'&&(f=-1),c=gc());
    	for(;isdigit(c);now=now*10+c-'0',c=gc());
    	return now*f;
    }
    inline bool Check(Line a,Line b,Line c){//p(a&b) is on the left of p(b&c)
    	return 1ll*(b.b-a.b)*(c.k-b.k)<=1ll*(b.b-c.b)*(a.k-b.k);
    }
    void Convex(Line *l,Line *sk,int &top)
    {
    	std::sort(l+1,l+1+n);
    	sk[top=1]=l[1];
    	for(int i=2; i<=n; ++i)
    	{
    		if(l[i].k==l[i-1].k) continue;
    		while(top>1 && Check(l[i],sk[top-1],sk[top])) --top;
    		sk[++top]=l[i];
    	}
    }
    #define F(i,x) (line[i].k*x+line[i].b)
    LL Find_Max(Line *line,int r,int x)
    {
    	int l=1,mid;
    	while(l<r)
    	{
    		mid=l+r>>1;
    		if(F(mid,x)>F(mid+1,x)) r=mid;
    		else l=mid+1;
    	}
    	return 1ll*x*F(l,x);
    }
    
    int main()
    {
    	n=read(); int Q=read();
    	for(int i=1,a,b; i<=n; ++i)
    		a=read(),b=read(),lu[i]=Line(a,b),ld[i]=Line(-a,-b);
    	int cntu,cntd;
    	Convex(lu,cu,cntu), Convex(ld,cd,cntd);
    	for(int x; Q--; )
    	{
    		x=read();
    		if(!x) puts("0");
    		else if(ans[x+32323]) printf("%lld
    ",ans[x+32323]);
    		else if(x>0) printf("%lld
    ",ans[x+32323]=Find_Max(cu,cntu,x));
    		else printf("%lld
    ",ans[x+32323]=-Find_Max(cd,cntd,x));
    	}
    	return 0;
    }
    

    B(思路 独立 期望)

    题目链接

    答案就是所有元素期望被减的次数。(当然(a_1)是一定会被减掉的)
    考虑某一局面,(i(i eq1))被减的期望次数是多少。所有元素被减的概率都是相同的。因为次数只与当前的(a_1,a_i)有关,且无论其它元素怎么变,1和i被减的概率都相同。
    即其它元素对考虑它们没有影响,这个问题就等价于只有两个元素的原问题。(等价很厉害啊,与其它无关且概率相同概率就都是(frac{1}{2})了)
    因此元素之间是独立的。对每个(a_i)计算答案求和就可以了。
    对于只有两个元素的问题,相当于从点((a_1,a_2))出发,每次等概率向左或向下走一步,直至走到坐标轴。若走到((0,x)),则对答案贡献(a_2-x);若走到((x,0)),则对答案贡献(a_2)
    或者考虑枚举(a_2)(a_1)被减到0前减了多少次。

    [sum_{i=0}^{a_2-1}i*frac{C_{a_1-1+i}^i}{2^{a_1+i}}+a_2(1-sum_{i=0}^{a_2-1}frac{C_{a_1-1+i}^i}{2^{a_1+i}}) ]

    前面是(a_2)未被减至0的期望次数,后面是被减至0的期望次数(概率用(1-sum_{i=0}^{a_2-1}frac{C_{a_1-1+i}^i}{2^{a_1+i}})就可以啊)。
    (a_2)每次增加1,前后都只会增加1项。算的时候直接用到(a_2)的前缀和也对,因为前后正好消掉。
    复杂度(O(a+n))

    #include <cstdio>
    #include <cctype>
    #include <algorithm>
    //#define gc() getchar()
    #define MAXIN 300000
    #define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++)
    #define mod 323232323
    typedef long long LL;
    const int N=1e6+5;
    
    int n,A[N>>1],fac[N],inv[N],inv2[N],f[N],p[N];
    char IN[MAXIN],*SS=IN,*TT=IN;
    
    #define C(n,m) (1ll*fac[(n)]*inv[(m)]%mod*inv[(n)-(m)]%mod)
    inline int read()
    {
    	int now=0;register char c=gc();
    	for(;!isdigit(c);c=gc());
    	for(;isdigit(c);now=now*10+c-'0',c=gc());
    	return now;
    }
    inline int FP(int x,int k)
    {
    	int t=1;
    	for(; k; k>>=1,x=1ll*x*x%mod)
    		if(k&1) t=1ll*t*x%mod;
    	return t;
    }
    
    int main()
    {
    	n=read(); int mx=0;
    	for(int i=1; i<=n; ++i) mx=std::max(mx,A[i]=read());
    	int a1=A[1], lim=a1+mx; fac[0]=1;
    	for(int i=1; i<=lim; ++i) fac[i]=1ll*fac[i-1]*i%mod;
    	inv[lim]=FP(fac[lim],mod-2);
    	for(int i=lim-1; ~i; --i) inv[i]=1ll*inv[i+1]*(i+1)%mod;
    	int i2=FP(2,mod-2); inv2[0]=1;
    	for(int i=1; i<=lim; ++i) inv2[i]=1ll*inv2[i-1]*i2%mod;//2^{-i}
    
    	p[0]=inv2[a1];
    	for(int i=1; i<=mx; ++i)
    	{
    		p[i]=1ll*C(a1+i-1,i)*inv2[a1+i]%mod, f[i]=1ll*i*p[i]%mod;
    		p[i]+=p[i-1], p[i]>=mod&&(p[i]-=mod);
    		f[i]+=f[i-1], f[i]>=mod&&(f[i]-=mod);
    	}
    	LL ans=a1;
    	for(int i=2; i<=n; ++i) ans+=f[A[i]/*-1*/]+1ll*A[i]*(mod+1-p[A[i]/*-1*/])%mod;
    	printf("%d
    ",(int)(ans%mod));
    
    	return 0;
    }
    

    C

    题目链接

    
    

    考试代码

    A

    #include <cstdio>
    #include <cctype>
    #include <algorithm>
    //#define gc() getchar()
    #define MAXIN 300000
    #define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++)
    typedef long long LL;
    const int N=5e5+5;
    
    int n,Q,A[N],B[N];
    LL ans[32323*4];
    char IN[MAXIN],*SS=IN,*TT=IN;
    
    inline int read()
    {
    	int now=0,f=1;register char c=gc();
    	for(;!isdigit(c);c=='-'&&(f=-1),c=gc());
    	for(;isdigit(c);now=now*10+c-'0',c=gc());
    	return now*f;
    }
    inline LL F(int x)
    {
    	int xx=x*x;
    	LL res=1ll*A[1]*xx+(LL)B[1]*x;
    	for(int i=2; i<=n; ++i) res=std::max(res,1ll*A[i]*xx+(LL)B[i]*x);
    	return res;
    }
    
    int main()
    {
    //	freopen(".in","r",stdin);
    //	freopen(".out","w",stdout);
    
    	n=read(), Q=read();
    	for(int i=1; i<=n; ++i) A[i]=read(),B[i]=read();
    	for(int i=1,x; i<=Q; ++i)
    	{
    		x=read();
    		if(ans[x+32323]) printf("%lld
    ",ans[x+32323]);
    		else printf("%lld
    ",ans[x+32323]=F(x));
    	}
    	return 0;
    }
    

    B

    #include <cstdio>
    #include <cctype>
    #include <algorithm>
    #define gc() getchar()
    #define mod 323232323
    typedef long long LL;
    const int N=5e5+5;
    
    int n,A[N],fac[N<<1],inv[N<<1],i2[N<<1];
    struct Fraction
    {
    	LL x,y;
    	Fraction() {x=0, y=1;}
    	Fraction(LL x,LL y):x(x),y(y) {}
    	LL Gcd(LL x,LL y){
    		return y?Gcd(y,x%y):x;
    	}
    	void Exgcd(LL a,LL b,LL &x,LL &y)
    	{
    		if(!b) x=1, y=0;
    		else Exgcd(b,a%b,y,x),y-=a/b*x;
    	}
    	void Fix() {LL g=Gcd(x,y); x/=g, y/=g;}
    	Fraction operator +(const Fraction &f)
    	{
    		LL a=x*f.y+y*f.x,b=y*f.y,g=Gcd(a,b);
    //		printf("%I64d/%I64d + %I64d/%I64d = %I64d/%I64d
    ",x,y,f.x,f.y,a/g,b/g);
    		return Fraction(a/g,b/g);
    	}
    	Fraction operator +(LL f)
    	{
    		LL a=f*y+x,g=Gcd(a,y);
    		return Fraction(a/g,y/g);
    	}
    	Fraction operator *(LL f)
    	{
    		LL a=x*f,g=Gcd(a,y);
    		return Fraction(a/g,y/g);
    	}
    //	Fraction operator *(const Fraction &f)
    //	{
    //		LL a=x*f.x,b=y*f.y,g=Gcd(a,b);
    //		return Fraction(a/g,b/g);
    //	}
    	void Print()
    	{
    		LL a,b; Exgcd(y,mod,a,b);
    		a=(a%mod+mod)%mod;//!
    //		printf("
    %I64d/%I64d=",x,y);
    		printf("%d
    ",(int)(a*x%mod));
    	}
    }Ans;
    
    inline int read()
    {
    	int now=0;register char c=gc();
    	for(;!isdigit(c);c=gc());
    	for(;isdigit(c);now=now*10+c-'0',c=gc());
    	return now;
    }
    inline int FP(int x,int k)
    {
    	int t=1;
    	for(; k; k>>=1,x=1ll*x*x%mod)
    		if(k&1) t=1ll*t*x%mod;
    	return t;
    }
    void DFS(int x,int t,LL p)
    {
    	if(!A[1])
    	{
    //		printf("%d %d*1/%I64d
    ",x,t,p);
    		Ans=Ans+Fraction(1,p)*t;
    		return;
    	}
    	for(int i=1; i<=n; ++i)
    		if(A[i]) --A[i], DFS(x+!A[i],t+1,p*(n-x)%mod), ++A[i];
    }
    bool Check2()
    {
    	for(int i=1; i<=n; ++i) if(A[i]>1) return 0;
    	return 1;
    }
    #define C(n,m) (1ll*fac[(n)]*inv[(m)]%mod*inv[(n)-(m)]%mod)
    //int c[1005][1005];
    //int C(int n,int m) {return c[n][m];}
    void Solve3()
    {
    //	c[0][0]=1;
    //	for(int i=1; i<1000; ++i)
    //	{
    //		c[i][0]=c[i][i]=1;
    //		for(int j=1; j<i; ++j)
    //			c[i][j]=(c[i-1][j-1]+c[i-1][j])%mod;
    //	}
    	int a1=A[1], a2=A[2], lim=a1+a2; fac[0]=1;
    	for(int i=1; i<=lim; ++i) fac[i]=1ll*fac[i-1]*i%mod;
    	inv[lim]=FP(fac[lim],mod-2), inv[0]=1;
    	for(int i=lim-1; i; --i) inv[i]=1ll*inv[i+1]*(i+1)%mod;
    	int inv2=FP(2,mod-2); i2[0]=1;
    	for(int i=1; i<=lim; ++i) i2[i]=1ll*i2[i-1]*inv2%mod;//2^{-i-1}
    	LL ans=0;
    	for(int i=0; i<a2; ++i)
    		ans+=1ll*C(a1+i-1,i)*(a1+i)%mod*i2[a1+i]%mod;
    	for(int i=a2; i<lim; ++i)
    		ans+=1ll*C(i-1,a2-1)*lim%mod*i2[i]%mod;
    	printf("%d
    ",(int)(ans%mod));
    }
    
    int main()
    {
    //	freopen("B.in","r",stdin);
    
    	n=read();
    	for(int i=1; i<=n; ++i) A[i]=read();
    	if(n==1) return printf("%d
    ",A[1]),0;
    //	DFS(0,0,1); Ans.Print();
    	if(n<=5&&A[1]<=5&&A[2]<=5) {DFS(0,0,1); Ans.Print(); return 0;}
    	if(Check2()) {Fraction(n+1,2).Print(); return 0;}
    	if(n==2) {Solve3(); return 0;}
    	printf("%d
    ",202020207);
    
    	return 0;
    }
    

    C

    #include <cstdio>
    #include <cctype>
    #include <algorithm>
    //#define gc() getchar()
    #define MAXIN 300000
    #define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++)
    typedef long long LL;
    const int N=3e5+5;
    
    int n,Q,A[N],dis[N],Enum,H[N],nxt[N<<1],to[N<<1],top[N],dep[N],fa[N],sz[N],son[N],dgr[N];
    LL Ans[N];
    char IN[MAXIN],*SS=IN,*TT=IN;
    
    inline int read()
    {
    	int now=0;register char c=gc();
    	for(;!isdigit(c);c=gc());
    	for(;isdigit(c);now=now*10+c-'0',c=gc());
    	return now;
    }
    inline void AddEdge(int u,int v)
    {
    	++dgr[v], to[++Enum]=v, nxt[Enum]=H[u], H[u]=Enum;
    	++dgr[u], to[++Enum]=u, nxt[Enum]=H[v], H[v]=Enum;
    }
    inline int LCA(int u,int v)
    {
    	while(top[u]!=top[v]) dep[top[u]]>dep[top[v]]?u=fa[top[u]]:v=fa[top[v]];
    	return dep[u]>dep[v]?v:u;
    }
    void DFS1(int x)
    {
    	int mx=0; sz[x]=1;
    	for(int v,i=H[x]; i; i=nxt[i])
    		if((v=to[i])!=fa[x])
    		{
    			dis[v]=dis[x]+1, fa[v]=x, dep[v]=dep[x]+1, DFS1(v), sz[x]+=sz[v];
    			if(mx<sz[v]) mx=sz[v], son[x]=v;
    		}
    }
    void DFS2(int x,int tp)
    {
    	top[x]=tp;
    	if(son[x])
    	{
    		DFS2(son[x],tp);
    		for(int i=H[x]; i; i=nxt[i])
    			if(to[i]!=fa[x]&&to[i]!=son[x]) DFS2(to[i],to[i]);
    	}
    }
    void DFS(int x,int f,int d)
    {
    	Ans[x]=Ans[f]+(A[x]|d);
    	for(int i=H[x]; i; i=nxt[i])
    		if(to[i]!=f) DFS(to[i],x,d+1);
    }
    void Spec()
    {
    	DFS(1,1,0);
    	for(int u,v; Q--; )
    	{
    		u=read(), v=read();
    		if(u==1) std::swap(u,v);
    		printf("%lld
    ",Ans[u]);
    	}
    }
    
    int main()
    {
    //	freopen("C.in","r",stdin);
    //	freopen(".out","w",stdout);
    
    	n=read(), Q=read();
    	for(int i=1; i<=n; ++i) A[i]=read();
    	for(int i=1; i<n; ++i) AddEdge(read(),read());
    	if(n>5000) {Spec(); return 0;}
    	DFS1(1), DFS2(1,1);
    	for(int u,v,w; Q--; )
    	{
    		u=read(), v=read(), w=LCA(u,v);
    		LL ans=A[w]|(dis[u]-dis[w]);
    		for(int x=u,d=0; x!=w; x=fa[x],++d) ans+=A[x]|d;
    		for(int x=v,d=dis[u]+dis[v]-(dis[w]<<1); x!=w; x=fa[x],--d) ans+=A[x]|d;
    		printf("%lld
    ",ans);
    	}
    	return 0;
    }
    
  • 相关阅读:
    hashCode() vs equals() vs ==
    DELPHI 关于 Style 的几点
    定制Mybatis拦截器开发【含源码追溯】
    Kubernetes 安装手册(非高可用版)
    查询组织数据,根据父级编号形成组织树
    Win10使用Virtual Box和Vagrant搭建CentOS7虚拟机集群环境sunziren
    FastDFS安装和简介详细总结
    Docker从入门到精通
    三种移除list中的元素(可靠)
    请求响应浏览器时乱码
  • 原文地址:https://www.cnblogs.com/SovietPower/p/9574547.html
Copyright © 2020-2023  润新知