• 【2020省选模拟】题解


    T1

    神题

    显然先容斥lr+1l或r+1作为下界
    设下界和为ss
    假设最后总和为xx
    就相当于a1+a2+a3....+an=xa_1+a_2+a_3....+a_n=x解一个方程组
    解都为正整数的方案为(xs1n1){x-s-1choose n-1}
    要求正整数把l,rl,r都减一即可
    答案即为x>s(xs1n1)[x]=x>0(x1n1)[x+s]=x>=0(xn1)[x+s+1]sum_{x>s}{x-s-1choose n-1}[x合法]=sum_{x>0}{x-1choose n-1}[x+s合法]=sum_{x>=0}{xchoose n-1}[x+s+1合法]
    为了方便将s1s加1变成x>=0(xn1)[x+s]sum_{x>=0}{xchoose n-1}[x+s合法]

    考虑用范德蒙德恒等式拆开(范德蒙德恒等式对广义组合数仍成立)
    这个组合数(xn1)=i(x+si)(sn1i){xchoose n-1}=sum_{i}{x+schoose i}{-schoose n-1-i}

    这时候就只需要算ix>=s(xi)[x]sum_{i}sum_{x>=s}{xchoose i}[x合法]
    再拆开考虑每一位的贡献(xi)=j(xdDkji)(dDkj){xchoose i}=sum_{j}{x-d*D^kchoose j-i}{d*D^kchoose j}
    然后用数位dpdp求出这样个东西的贡献
    预处理转移时组合数系数前后缀和加快转移

    总复杂度O(2nn2500)O(2^nn^2*500)

    不知道为什么跑这么慢。。。。

    #include<bits/stdc++.h>
    using namespace std;
    #define cs const
    #define re register
    #define pb push_back
    #define pii pair<int,int>
    #define ll long long
    #define fi first
    #define se second
    #define bg begin
    cs int RLEN=1<<20|1;
    inline char gc(){
        static char ibuf[RLEN],*ib,*ob;
        (ib==ob)&&(ob=(ib=ibuf)+fread(ibuf,1,RLEN,stdin));
        return (ib==ob)?EOF:*ib++;
    }
    inline int read(){
        char ch=gc();
        int res=0;bool f=1;
        while(!isdigit(ch))f^=ch=='-',ch=gc();
        while(isdigit(ch))res=(res+(res<<2)<<1)+(ch^48),ch=gc();
        return f?res:-res;
    }
    inline int readstr(int *s){
    	int top=0;char ch=gc();
    	while(isspace(ch))ch=gc();
    	while(!isspace(ch))s[++top]=ch-'0',ch=gc();
    	return top;
    }
    template<class tp>inline void chemx(tp &a,tp b){a<b?a=b:0;}
    template<class tp>inline void chemn(tp &a,tp b){a>b?a=b:0;}
    cs int mod=1e9+7;
    inline int add(int a,int b){return (a+=b)>=mod?(a-mod):a;}
    inline int dec(int a,int b){a-=b;return a+(a>>31&mod);}
    inline int mul(int a,int b){static ll r;r=1ll*a*b;return (r>=mod)?(r%mod):r;}
    inline void Add(int &a,int b){(a+=b)>=mod?(a-=mod):0;}
    inline void Dec(int &a,int b){a-=b,a+=a>>31&mod;}
    inline void Mul(int &a,int b){static ll r;r=1ll*a*b;a=(r>=mod)?(r%mod):r;}
    inline int ksm(int a,int b,int res=1){for(;b;b>>=1,Mul(a,a))(b&1)&&(Mul(res,a),1);return res;}
    inline int Inv(int x){return ksm(x,mod-2);}
    inline int fix(int x){return (x<0)?x+mod:x;}
    cs int N=15,M=515;
    int D,n,C[M][M][N],pre[M][M][N],suf[M][M][N],ok[M];
    int inv[M];
    inline void readIn(vector<int> &a){
    	static int num[M*10],len;
    	len=readstr(num);
    	reverse(num+1,num+len+1);
    //	for(int i=1;i<=len;i++)cout<<num[i]<<" . ";puts("");
    	while(len){
    		int s=0;
    		for(int i=len;i;i--)
    			s=s*10+num[i],num[i]=s/D,s%=D;
    		a.pb(s);//cout<<s<<" ";
    		while(len&&num[len]==0)len--;
    	}//puts("");
    }
    struct bignum{
    	vector<int> a;
    	bignum(){a.clear();}
    	inline void clear(){a.clear();}
    	void read(){
    		readIn(a);
    	}
    	inline void del(){while(a.size()&&!a.back())a.pop_back();}
    	void operator ++(){
    		a.pb(0);a[0]++;
    		for(int i=0;i<a.size()-1;i++)
    		if(a[i]>=D)a[i]-=D,a[i+1]++;
    		del();
    	}
    	void operator --(){
    		if(!a.size())a.pb(0);a[0]--;
    		for(int i=0;i<(int)a.size()-1;i++)
    		if(a[i]<0)a[i]+=D,a[i+1]--;
    		del();
    	}
    	inline int len()cs{return a.size();}
    	friend inline bignum operator +(cs bignum &a,cs bignum &b){
    		bignum c;int len=max(a.len(),b.len());
    		c.a.resize(len);
    		for(int i=0;i<len;i++)c.a[i]=(a.len()>i?a.a[i]:0)+(b.len()>i?b.a[i]:0);
    		c.a.pb(0);
    		for(int i=0;i<len;i++)if(c.a[i]>=D)c.a[i]-=D,c.a[i+1]++;
    		c.del();return c;
    	}
    	inline int pos(int x){return a.size()>x?a[x]:0;}
    	inline int val(){int res=0;for(int i=(int)a.size()-1;~i;i--)res=add(mul(res,D),a[i]);return res;}
    };
    bignum L[N],R[N],dn;
    inline void init_inv(){
    	inv[0]=inv[1]=1;
    	for(int i=2;i<M;i++)inv[i]=mul(mod-mod/i,inv[mod%i]);
    }
    int g[2][N],f[2][N],s[N];
    inline int calc(){
    	memset(f,0,sizeof(f));
    	memset(s,0,sizeof(s));
    	f[1][0]=1;int cur=0;
    	for(int i=0;i<=510;i++){
    		int lim=dn.pos(i);
    		memcpy(g,f,sizeof(g));
    		memset(f,0,sizeof(f));
    		for(int x=0;x<n;x++)if(g[0][x]||g[1][x]){
    			int now=add(g[0][x],g[1][x]);
    			for(int y=0;x+y<n;y++){
    				if(lim)Add(f[0][x+y],mul(now,pre[i][lim-1][y]));
    				if(lim+1<D){
    					Add(f[1][x+y],mul(now,suf[i][lim+1][y]));
    					if(i+1>=dn.len())Add(s[x+y],mul(now,suf[i][lim+1][y]));
    				}
    				for(int t=0;t<2;t++)
    				Add(f[t][x+y],mul(g[t][x],C[i][lim][y]));
    				if(i+1==dn.len())Add(s[x+y],mul(g[1][x],C[i][lim][y]));
    			}
    		}
    	}
    	int v=dec(0,dn.val()),res=0,c=1;
    	for(int i=0;i<n;i++){
    		if(i)c=mul(c,mul(dec(v,i-1),inv[i]));
    		Add(res,mul(s[n-1-i],c));
    	}
    	return res;
    }
    int main(){
    	#ifdef Stargazer
    	freopen("lx.in","r",stdin);
    	#endif	
    	n=read(),D=read(),init_inv();
    	for(int i=0;i<D;i++)ok[i]=read();
    	for(int i=1;i<=n;i++)L[i].read(),R[i].read(),--L[i];
    	for(int i=0,pw=1,mt;i<=510;i++,Mul(pw,D)){
    		for(int d=0;d<D;d++)if(ok[d]){
    			C[i][d][0]=1,mt=mul(pw,d);
    			for(int j=1;j<=n;j++)
    			C[i][d][j]=mul(C[i][d][j-1],mul(dec(mt+1,j),inv[j]));
    		}
    		for(int j=0;j<=n;j++)pre[i][0][j]=C[i][0][j];
    		for(int d=1;d<D;d++)
    		for(int j=0;j<n;j++)
    			pre[i][d][j]=add(pre[i][d-1][j],C[i][d][j]);//,cout<<pre[i][d][j]<<'
    ';;
    		for(int j=0;j<=n;j++)suf[i][D-1][j]=C[i][D-1][j];
    		for(int d=D-2;~d;d--)
    		for(int j=0;j<n;j++)
    			suf[i][d][j]=add(suf[i][d+1][j],C[i][d][j]);//cout<<suf[i][d][j]<<'
    ';
    	}
    	int res=0;
    	for(int s=0;s<(1<<n);s++){
    		dn.clear();int siz=0;
    		for(int i=0;i<n;i++)
    		if(s&(1<<i))siz++,dn=dn+R[i+1];
    		else dn=dn+L[i+1];
    	//	for(int i=0;i<dn.a.size();i++)cout<<dn.a[i]<<" ";puts("");
    		++dn;
    		if(siz&1)Dec(res,calc());
    		else Add(res,calc());
    	}
    	cout<<res<<'
    ';
    }
    

    T2:

    预处理每两点间距离枚举两条边分类讨论贡献即可
    stdstd没考虑一条边的情况。。。

    #include<bits/stdc++.h>
    using namespace std;
    #define cs const
    #define re register
    #define pb push_back
    #define pii pair<int,int>
    #define ll long long
    #define fi first
    #define se second
    #define bg begin
    cs int RLEN=1<<20|1;
    inline char gc(){
        static char ibuf[RLEN],*ib,*ob;
        (ib==ob)&&(ob=(ib=ibuf)+fread(ibuf,1,RLEN,stdin));
        return (ib==ob)?EOF:*ib++;
    }
    inline int read(){
        char ch=gc();
        int res=0;bool f=1;
        while(!isdigit(ch))f^=ch=='-',ch=gc();
        while(isdigit(ch))res=(res+(res<<2)<<1)+(ch^48),ch=gc();
        return f?res:-res;
    }
    template<class tp>inline void chemx(tp &a,tp b){a<b?a=b:0;}
    template<class tp>inline void chemn(tp &a,tp b){a>b?a=b:0;}
    cs int N=5005;
    int dis[N][N];
    vector<pii> e[N];
    struct edge{
    	int u,v,w;
    }E[N];
    int n,m,ans,vis[N];
    priority_queue<pii,vector<pii>,greater<pii> > q;
    inline void dijkstra(int str,int *dis){
    	memset(vis,0,sizeof(int)*(n+1));
    	dis[str]=0;q.push(pii(0,str));
    	while(!q.empty()){
    		int u=q.top().se;q.pop();
    		if(vis[u])continue;vis[u]=1; 
    		for(pii &x:e[u]){
    			if(dis[x.fi]>dis[u]+x.se){
    				dis[x.fi]=dis[u]+x.se;
    				q.push(pii(dis[x.fi],x.fi));
    			}
    		}
    	}
    }
    inline int calc(int a,int b,int c,int d,int lx,int ly){
    	chemn(ly,(b-a)/2),chemn(lx,(c-a)/2);
    	return a+min(lx+ly,(d-a)/2);
    }
    inline int calc(edge x,edge y){
    	int a=dis[x.u][y.u],b=dis[x.u][y.v],c=dis[x.v][y.u],d=dis[x.v][y.v],e=x.w,f=y.w;
    	return max(max(calc(a,b+f,c+e,d+e+f,e,f),calc(b,a+f,d+e,c+e+f,e,f)),max(calc(c,d+f,a+e,b+e+f,e,f),calc(d,c+f,b+e,a+e+f,e,f)));
    }
    inline void solve(){
    	n=read(),m=read(),ans=0;
    	for(int i=1;i<=m;i++){
    		int u=read(),v=read(),w=read()*2;
    		E[i].u=u,E[i].v=v,E[i].w=w;
    		chemx(ans,w/2);
    		e[u].pb(pii(v,w)),e[v].pb(pii(u,w));
    	}
    	for(int i=1;i<=n;i++){
    		memset(dis[i],127/3,sizeof(int)*(n+1));
    		dijkstra(i,dis[i]);
    	}
    	for(int i=1;i<=m;i++)
    	for(int j=i+1;j<=m;j++)
    	chemx(ans,calc(E[i],E[j]));
    	printf("%.1lf
    ",1.0*ans/2);
    	for(int i=1;i<=n;i++)
    	memset(dis[i],0,sizeof(int)*(n+1)),e[i].clear();
    }
    int main(){
    	int T=read();
    	while(T--)solve();
    }
    

    T3:

    凸包dpdp

    考虑先枚举一个凸包的最左端点oo
    其余点按照极角排序
    f[i][j]f[i][j]表示当前凸包最后一个点为jj,上一个点为ii的方案数
    考虑枚举ii转移
    由于要满足凸包性质,所以可以按照ii的极角利用单调性O(n)O(n)转移
    然后按对于ii极角从大到小对于每个jj判断一下是否有点在o,i,jo,i,j的三角形内即可

    复杂度O(n3)O(n^3)

    #include<bits/stdc++.h>
    using namespace std;
    #define cs const
    #define re register
    #define pb push_back
    #define pii pair<int,int>
    #define ll long long
    #define fi first
    #define se second
    #define bg begin
    cs int RLEN=1<<20|1;
    inline char gc(){
        static char ibuf[RLEN],*ib,*ob;
        (ib==ob)&&(ob=(ib=ibuf)+fread(ibuf,1,RLEN,stdin));
        return (ib==ob)?EOF:*ib++;
    }
    inline int read(){
        char ch=gc();
        int res=0;bool f=1;
        while(!isdigit(ch))f^=ch=='-',ch=gc();
        while(isdigit(ch))res=(res+(res<<2)<<1)+(ch^48),ch=gc();
        return f?res:-res;
    }
    template<class tp>inline void chemx(tp &a,tp b){a<b?a=b:0;}
    template<class tp>inline void chemn(tp &a,tp b){a>b?a=b:0;}
    cs int mod=1e9+7;
    inline int add(int a,int b){return (a+=b)>=mod?(a-mod):a;}
    inline int dec(int a,int b){a-=b;return a+(a>>31&mod);}
    inline int mul(int a,int b){static ll r;r=1ll*a*b;return (r>=mod)?(r%mod):r;}
    inline void Add(int &a,int b){(a+=b)>=mod?(a-=mod):0;}
    inline void Dec(int &a,int b){a-=b,a+=a>>31&mod;}
    inline void Mul(int &a,int b){static ll r;r=1ll*a*b;a=(r>=mod)?(r%mod):r;}
    inline int ksm(int a,int b,int res=1){for(;b;b>>=1,Mul(a,a))(b&1)&&(Mul(res,a),1);return res;}
    inline int Inv(int x){return ksm(x,mod-2);}
    inline int fix(int x){return (x<0)?x+mod:x;}
    cs int N=505;
    struct pt{
    	int x,y;
    	pt(int _x=0,int _y=0):x(_x),y(_y){}
    	friend inline pt operator +(cs pt &a,cs pt &b){return pt(a.x+b.x,a.y+b.y);}
    	friend inline pt operator -(cs pt &a,cs pt &b){return pt(a.x-b.x,a.y-b.y);}
    	friend inline int operator *(cs pt &a,cs pt &b){return a.x*b.y-a.y*b.x;}
    }p[N];
    inline int cross(int a,int b,int c){
    	return (p[a]-p[c])*(p[b]-p[c]);
    }
    int tp;
    inline bool cmp(cs int &a,cs int &b){
    	return cross(a,b,tp)>0;
    }
    inline bool comp(cs pt &a,cs pt &b){
    	return a.x==b.x?a.y<b.y:a.x<b.x;
    }
    int f[N][N],id[N][N*2],ql[N],qr[N],tl,tr;
    int n,ans;
    int main(){
    	#ifdef Stargazer
    	freopen("lx.in","r",stdin);
    	#endif
    	n=read();
    	for(int i=1;i<=n;i++)p[i].x=read(),p[i].y=read();
    	sort(p+1,p+n+1,comp);
    	for(int i=1;i<=n;i++){
    		for(int j=1;j<=n;j++)id[i][j]=j;
    		id[i][i]=1;tp=i;
    		sort(id[i]+2,id[i]+i+1,cmp);
    		sort(id[i]+i+1,id[i]+n+1,cmp);
    		for(int j=n+1;j<2*n;j++)id[i][j]=id[i][j-n+1];
    	}
    	for(int i=1;i<=n;i++){
    		memset(f,0,sizeof(f));
    		for(int j=i+1;j<=n;j++){
    			int p=id[i][j],ps=0;
    			tl=tr=0;
    			for(int k=2;k<=n;k++)if(id[p][k]==i){ps=k;break;}
    			for(int k=ps;k<ps+n;k++)if(id[p][k]>i){
    				if(cross(id[p][k],i,p)>0)qr[++tr]=id[p][k];
    				else ql[++tl]=id[p][k];
    			}
    			int s=0;
    			for(int l=1,r=1;r<=tr;){
    				if(l>tl||cross(ql[l],qr[r],p)>0)
    				Add(f[p][qr[r]],s),r++;
    				else Add(s,f[ql[l]][p]),l++;
    			}
    			int pre=0;
    			while(tr){
    				if(!pre||cross(qr[tr],pre,i)>0)
    				Add(f[p][qr[tr]],1),pre=qr[tr];
    				else f[p][qr[tr]]=0;
    				tr--;
    			}
    			for(int k=j+1;k<=n;k++)Add(ans,f[p][id[i][k]]);
    		}
    	}
    	cout<<ans<<'
    ';
    }
    
    
  • 相关阅读:
    微信小程序全屏飘落效果(飘雪、掉落、canvas)
    放在cnblogs上的文件资源
    JavaScript笔记Array.filter(Boolean)
    webpack 4.0 配置文件 webpack.config.js文件的放置位置
    package.json中^,~的区别
    你不知道的 JSON.stringify() 的威力
    vue+axios通过formdata提交参数和上传文件
    webstorm激活教程----亲测可用
    git修改远程仓库地址
    微信小程序通讯录字母排序
  • 原文地址:https://www.cnblogs.com/stargazer-cyk/p/12328285.html
Copyright © 2020-2023  润新知