zoukankan      html  css  js  c++  java
  • [20180819]四校联考

    不要问我8.19的题为什么今天才写完,因为我弱啊

    T1 扫雷(mine)

    Problem戳这里

    Solution:


    显然,(ans = min_{i=1}^n frac{bi}{ai}),令cnt为满足ans的个数,方案数即(2^{cnt }-1),用快速幂来求。

    另外,本题卡精度,你当然可以向XMJJSW一样写一个分数类,也可以对输入的数成(10^8), 用整形判断

    不过最方便的还是设个eps,取个1e-12即可以了。


    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #define MN 1000005
    double a[MN],b[MN];
    long long num,n,ans;
    #define mod 998442553
    #define eps 1e-12 
    #define sign(a) ((a>(-eps))-(a<eps))
    inline bool cmp(const int&x,const int&y){
    	return sign(a[x]*b[y]-b[x]*a[y])==1;
    }
    long long Quick_pow(long long m,long long p){
    	long long res=1;
    	while(p){
    		if(p&1) res=(res*m)%mod,p-=1;
    		else m=(m*m)%mod,p>>=1;
    	}
    	return res;
    }
    int main(){
    	freopen("mine.in","r",stdin);
    	freopen("mine.out","w",stdout);
    	int T;scanf("%d
    ",&T);
    	while(T--){
    		scanf("%d",&n);register int i;
    		for(i=1;i<=n;i++) scanf("%lf",&a[i]);
    		for(i=1;i<=n;i++) scanf("%lf",&b[i]);
    		ans=1;num=0;
    		for(i=2;i<=n;i++) if(cmp(i,ans)) ans=i;
    		for(i=1;i<=n;i++){
    			if(sign(a[i]*b[ans]-a[ans]*b[i])==0) num++;
    		}
    		if(sign(b[ans]-a[ans]*10000.0)==1){
    			puts("Impossible");continue;
    		}
    		num=(Quick_pow(2,num)+mod-1)%mod;
    		printf("%.8lf %lld
    ",b[ans]/a[ans],num);
    	}
    	return 0;
    }
    




    T2 信息组的裁员(cut)

    Problem戳这里

    Solution:


    对于30%的数据,可以使用O((m^2))的简单dp。

    对于60%的数据,可以贪心,也很好想。

    对于100%的数据,考虑贪心的优化。

    官方题解:


    嗯,完美。


    //30分的dp
    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    inline long long read(){
    	long long x=0,f=1;char ch=getchar();
    	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    	while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
    	return x*f;
    }
    #define MN 6000005
    long long n,m,a[MN],q[MN];
    long long num,sum,f[2][MN];
    int main(){
    	freopen("cut.in","r",stdin);
    	freopen("cut.out","w",stdout);
    	n=read();m=read();
    	register int i,j;
    	for(i=1;i<=n;i++) a[i]=read(),q[i]=q[i-1]+a[i];
    	for(i=1;i<=n;i++) if(a[i]>=0){
    		j=i;num++;while(a[i+1]>=0&&i<n) i++;
    		sum+=q[i]-q[j-1];
    	}
    	if(num<=m) return 0*printf("%lld
    ",sum);
    	int now=1,last=0;
    	for(i=1;i<=n-m+1;i++) f[0][i]=std::max(f[0][i-1],q[i]);
    	for(i=2;i<=m;i++){
    		f[now][i]=q[i];
    		for(j=i+1;j<=i+n-m;j++) f[now][j]=a[j]+std::max(f[now][j-1],f[last][j-1]);
    		for(j=i+1;j<=i+n-m;j++) f[now][j]=std::max(f[now][j-1],f[now][j]);
    		now^=1;last^=1;
    	}
    	printf("%lld
    ",f[last][n]);
    	return 0;
    }
    



    #include<bits/stdc++.h>
    inline int read(){
    	int x=0,f=1;char ch=getchar();
    	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    	while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
    	return x*f;
    }
    #define abs(a) (((a)>0)?(a):-(a))
    #define cmin(a,b) (a>(b)?a=(b),1:0)
    #define cmax(a,b) (a<(b)?a=(b),1:0)
    #define dmin(a,b) ((a)<(b)?(a):(b))
    #define dmax(a,b) ((a)>(b)?(a):(b))
    typedef long long ll;
    #define MN 6000005
    struct data{
    	ll val;int pos;
    	data(ll v=0,int p=0){val=v;pos=p;}
    	bool operator< (const data &o) const{return val<o.val||val==o.val&&pos<o.pos;}
    	bool operator<=(const data &o) const{return val<o.val||val==o.val&&pos<=o.pos;}
    }t[MN],mx,mx2;
    ll a[MN],ans;
    int remain,n,m,q[MN],hq,tq,cnt,l[MN],r[MN],L[MN],R[MN];
    bool inq[MN],del[MN],Del[MN];
    void AddQue(int i){
    	if(i&&(!inq[i])&&data(abs(a[i]),i)<=mx) q[++tq]=i,inq[i]=true;
    }
    void dele(int x){
    	if((!x)||del[x]) return ;
    	r[l[x]]=r[x];l[r[x]]=l[x];
    	del[x]=true;
    }
    void Dele(int x){
    	if((!x)||Del[x]) return ;
    	remain--;R[L[x]]=R[x];L[R[x]]=L[x];
    	Del[x]=true;dele(x);
    }
    void Merge(int x){
    	if(Del[x]) return ;
    	int lef=L[x],rig=R[x];
    	if(lef&&abs(a[lef])<abs(a[x])) return ;
    	if(rig&&abs(a[rig])<abs(a[x])) return ;
    	Dele(lef);Dele(rig);a[x]+=a[lef]+a[rig];
    	lef&&rig?AddQue(x):Dele(x);
    	AddQue(lef);AddQue(rig); 
    }
    int main(){
    	freopen("cut.in","r",stdin);
    	freopen("cut.out","w",stdout);
    	n=read();m=read();int i,j,x;
    	for(i=1,j=0;i<=n;i++){
    		a[++j]=read();if(a[j]==0||j==1&&a[j]<0)--j;
    		if(j>1&&(a[j]>0)^(a[j-1]<0)) a[j-1]+=a[j],--j; 
    	}if(j>0&&a[j]<0) --j;
        for(i=0;i<=j;i++)
        	r[i]=R[i]=(i+1)%(j+1),l[i]=L[i]=(i+j)%(j+1);
        remain=j;
        while(1){
        	cnt=0;hq=1;tq=0;
        	for(i=r[0];i;i=r[i]) t[++cnt]=data(abs(a[i]),i);
        	if(remain<(m<<1)) break;
        	int mid=(remain-(m<<1)+1)>>1;
        	std::nth_element(t+1,t+dmin(mid,cnt)+1,t+cnt+1);
            mx=t[dmin(mid,cnt)];
            std::nth_element(t+1,t+dmin(mid*3,cnt)+1,t+cnt+1);
            mx2=t[dmin(mid*3,cnt)];
            for(i=r[0];i;i=r[i]){
                data cur(abs(a[i]),i);
                if(mx2<cur) dele(i);
                else AddQue(i);
            }
            for(;hq<=tq;++hq)
            	inq[q[hq]]=false,Merge(q[hq]);
    	}ans=0;
        for(i=R[0];i;i=R[i]) if(a[i]>0) ans+=1ll*a[i];
        printf("%lld
    ",ans);
        return 0;
    }
    




    T3 已傻的结合(ishhac)

    Problem戳这里

    Solution:


    1. dp方程:(a=0的时候)

      [f_{k,i,j}=min_{x}^n max {f_{k-1,i,x},g_{x,j}}$$其中,`g[x][j]`表示x到j的边权。 ]

    2. 因为T<=4,所以图的一个周期是12,所以$$G_i=G_{i mod 12}$$.

      分别求出这12个矩阵,命名为A1~A12,则最终矩阵是

      [R= A_{12}^{leftlfloorfrac{K}{12} ight floor}Phi A_{K mod 12} ]

      用矩阵快速幂求(A_{12}^{leftlfloorfrac{K}{12} ight floor})即可。


    膜一下大佬的代码:

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    const int inf = 0x3f3f3f3f;
    typedef long long LL;
    LL ri() {
        char c = getchar(); LL x = 0; for(;c < '0' || c > '9'; c = getchar()) ;
        for(;c >= '0' && c <= '9';  c = getchar()) x = (x << 1) + (x << 3) - '0' + c; return x;
    }
    struct Maxtir {
        int n, m[60][60];
        void Init() {n = 0; std::memset(m, 0x3f, sizeof(m));}
        Maxtir operator * (Maxtir a) {
            Maxtir b; b.n = a.n;
            for(int i = 1;i <= n; ++i)
                for(int j = 1;j <= n; ++j) {
                    b.m[i][j] = inf;
                    for(int k = 1;k <= n; ++k)
                        b.m[i][j] = std::min(b.m[i][j], std::max(a.m[k][j], m[i][k]));
                }
            return b;
        }
    }a, b, c[13];
    int n, m, s, t; LL K;
    void Pow(Maxtir &a, LL x) {Maxtir b = a; x--; for(;x; b = b * b, x >>= 1) if(x & 1) a = a * b;}
    int main() {
    	freopen("ishaac.in","r",stdin);
    	freopen("ishaac.out","w",stdout);
    	for(int C = ri(); C--;) {
    		a.Init(); n = ri(); m = ri(); s = ri(); t = ri(); K = ri(); a.n = n;
    	    for(int i = 1, u, v, w;i <= m; ++i)
    	        u = ri(), v = ri(), w = ri(), a.m[u][v] = a.m[v][u] = w;
    	    for(int i = 1;i <= 12; ++i) c[i] = a;
    	    int nf = ri();
    	    for(int i = 1, T, j, x, k;i <= nf; ++i)
    	        for(T = ri(), j = 0;j < T; ++j)
    	            for(x = ri(), k = j;k <= 12; k += T)
    	                for(int p = 1;p <= n; ++p)
    	                c[k].m[p][x] = inf;
    	    a = c[1];
    	    if(K <= 12) {
    	        for(int i = 2;i <= K; ++i) a = a * c[i];
    	        a.m[s][t] == inf ? puts("impossible") : printf("%d
    ", a.m[s][t]);
    	        continue;
    	    }
    	    for(int i = 2;i <= 12; ++i) a = a * c[i];
    	    Pow(a, K / 12);
    	    for(int i = 1;i <= K % 12; ++i) a = a * c[i];
    	    a.m[s][t] == inf ? puts("impossible") : printf("%d
    ", a.m[s][t]);
    	}
        return 0;
    }
    





    Blog来自PaperCloud,未经允许,请勿转载,TKS!

  • 相关阅读:
    关于 NSTimer 和 NSRunLoop 的一些理解
    通过 CocoaPods 集成 WeexSDK 到iOS项目中
    iOS 从相册取出的图片默认 取中间部分 裁剪成方形的
    Trilynn分享了炼数成金邀请码
    highcharts分段显示不同颜色
    H5手机开发锁定表头和首列(惯性滚动)解决方案
    为移动端开发提供纯前端的路由方案
    ionic系列
    2014总结
    margin 相关 bug 系列
  • 原文地址:https://www.cnblogs.com/PaperCloud/p/9527320.html
Copyright © 2011-2022 走看看