zoukankan      html  css  js  c++  java
  • BestCoder Round #86 解题报告

    A.Price List

    Sol

    求和查询

    Code

    #include<cstdio>
    #include<algorithm>
    #include<iostream>
    using namespace std;
    
    typedef long long LL;
    const int N = 100005;
    
    //LL v[N];
    
    inline LL in(LL x=0,char ch=getchar()){ while(ch>'9'||ch<'0') ch=getchar();
        while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();return x; }
    int main(){
        int T,n,m;LL tmp;
        for(T=in();T--;){
            n=in(),m=in(),tmp=0;
            for(int i=1;i<=n;i++) tmp+=in();
    //        for(int i=1;i<=n;i++) v[i]=in();
            for(int i=1;i<=m;i++){
                if(in()>tmp) putchar('1');
                else putchar('0');
            }putchar('
    ');
        }return 0;
    }
    

    B.NanoApe Loves Sequence

    Sol

    统计出来前面最大的绝对值,后面最大的绝对值,然后枚举中间位置就可以了.

    Code

    #include<cstdio>
    #include<iostream>
    using namespace std;
    
    const int N = 100005;
    
    int T,n,a[N],p[N],q[N];
    long long ans;
    
    //inline int in(int x=0,char ch=getchar()){ while(ch>'9'||ch<'0') ch=getchar();
    //    while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();return x; }
    inline int abs(int x){ return x<0?-x:x; }
    int main(){
        for(cin>>T;T--;){
    //        n=in();for(int i=1;i<=n;i++) a[i]=in();
            scanf("%d",&n);
            memset(a,0,sizeof(a));
            memset(p,0,sizeof(p));
            memset(q,0,sizeof(q));
            for(int i=1;i<=n;i++) scanf("%d",&a[i]);
            for(int i=2;i<=n;i++) p[i]=max(p[i-1],abs(a[i]-a[i-1]));
            for(int i=n-1;i;i--) q[i]=max(q[i+1],abs(a[i]-a[i+1]));
            
    //        for(int i=1;i<=n;i++) cout<<p[i]<<" ";cout<<endl;
    //        for(int i=1;i<=n;i++) cout<<q[i]<<" ";cout<<endl;
            
            ans=q[2]+p[n-1];
            for(int i=2;i<n;i++) ans+=max(abs(a[i-1]-a[i+1]),max(p[i-1],q[i+1]));
            cout<<ans<<endl;
        }
        return 0;
    }
    

      


    C.NanoApe Loves Sequence Ⅱ

    Sol

    枚举左端点,做尺取法就可以了.

    Code

    #include<cstdio>
    #include<iostream>
    using namespace std;
    int p[200005];
    int n,m,k;
    int T,x;
    long long ans;
    int main(){
        int i,j;
        scanf("%d",&T);
        while(T--){
            ans=0;
            scanf("%d%d%d",&n,&m,&k);
            for(i=1;i<=n;i++){
                scanf("%d",&x);
                if(x>=m) p[i]=1+p[i-1];
                else p[i]=p[i-1];
            }
            for(i=1,j=1;i<=n;i++){
                for(;p[j]-p[i-1]<k&&j<=n;j++);
                ans+=n-j+1;
            }cout<<ans<<endl;
        }return 0;
    }
    

      


    D.Keep In Touch

    Sol

    DAG上的DP.

    注意输入的时候 (u<v) 这就保证了是一个有向无环图,我当时没注意,一直在想有环怎么做.

    (f[i][j][k]) 表示第1个人第2个人第3个人的位置分别为 (i) , (j) ,(k) 的方案数.

    然后直接DP是 (O(n^6)) ,加一维表示当前考虑到了第 (p) 个人.

    注意转移的时候只需要判断第1个人是否合法就可以了,因为第2.3个人还没有走到相应的位置.

    Code

    #include<cstdio>
    #include<cstring>
    #include<vector>
    #include<iostream>
    using namespace std;
    
    typedef long long LL;
    const int N = 55;
    const LL Mo = 998244353;
    
    int T,n,m,K,q;
    int w[N];
    LL f[N][N][N][4];
    vector<int> g[N];
    
    inline int in(int x=0,char ch=getchar()){ while(ch>'9'||ch<'0') ch=getchar();
    	while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();return x; }
    inline int abs(int x){ return x<0?-x:x; }
    inline int check(int a,int b,int c){
    	if(abs(w[a]-w[b])>K||abs(w[a]-w[c])>K||abs(w[b]-w[c])>K) return 0;
    	return 1;
    }
    int main(){
    //	freopen("in.in","r",stdin);
    	for(T=in();T--;){
    		memset(f,0,sizeof(f));for(int i=0;i<N;i++) g[i].clear();
    		n=in(),m=in(),K=in(),q=in();
    		for(int i=1;i<=n;i++) w[i]=in();
    		
    		for(int i=1,u,v;i<=m;i++) u=in(),v=in(),g[u].push_back(v);
    		
    		for(int i=n;i;i--) for(int j=n;j;j--) for(int k=n;k;k--){
    			f[i][j][k][1]=1;
    			for(int p=0;p<g[i].size();p++) f[i][j][k][1]=(f[i][j][k][1]+f[g[i][p]][j][k][3])%Mo;
    			for(int p=0;p<g[j].size();p++) f[i][j][k][2]=(f[i][j][k][2]+f[i][g[j][p]][k][1])%Mo;
    			for(int p=0;p<g[k].size();p++) f[i][j][k][3]=(f[i][j][k][3]+f[i][j][g[k][p]][2])%Mo;
    			if(!check(i,j,k)) f[i][j][k][1]=0;
    		}
    		
    //		for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) for(int k=1;k<=n;k++)
    //			cout<<i<<" "<<j<<" "<<k<<"-->"<<f[i][j][k][1]<<" "<<f[i][j][k][2]<<" "<<f[i][j][k][3]<<endl;
    		
    		for(int i=1,x,y,z;i<=q;i++){
    			x=in(),y=in(),z=in();
    			printf("%I64d
    ",f[x][y][z][1]);
    		}
    	}return 0;
    }
    

      


    E.Price List Strike Back

    Sol

    考虑对序列的分治,

    (Solve(l,r,L,R)) 表示处理左右端点在 ([l,r]) 中的问题 ([L,R]) .

    分三种情况 (r_i<=mid) (l_i>mid) (l_i<=mid<r_i)

    对于前两种情况我们扔到 (Solve(l,mid)) 和 (Solve(mid+1,r)) 中处理.

    跨过中间点 (mid) 的方案数可以用背包在 (O(100(r-l+1))) 的时间内处理出来.

    (f[i][j]) 表示从 (i) 到 (mid) 得到 (j) 的最长的最短距离.

    (g[i][j]) 表示从 (mid+1) 到 (i) 得到 (j) 的最长的最短距离.

    然后统计就是

    (c_i=min(c_i,max(f[l_i][j],g[r_i][s_i-j])))

    复杂度 (O(nlogn+m))

    PS:数组开小 T掉了...

    Code

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<iostream>
    using namespace std;
    
    const int N = 20005;
    const int QM = 100005;
    const int M = 105;
    const int INF = 0x7f7f7f7f;
    #define mid ((l+r)>>1)
    #define lc (o<<1)
    #define rc (o<<1|1)
    #define debug(a) cout<<#a<<"="<<a<<" "
    
    int T,n,m;
    int w[N],d[N];
    struct Q{ int l,r,s,c,id; }q[QM],tmp[QM];
    bool operator < (const Q &a,const Q &b){ return a.id<b.id; }
    int f[N][M],g[N][M];
    int ans[QM];
    
    inline int in(int x=0,char ch=getchar()){ while(ch>'9'||ch<'0') ch=getchar();
    	while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();return x; }
    void Solve(int l,int r,int L,int R){
    	if(L>R) return;
    	if(l==r){
    		if(L<=R) for(int i=L;i<=R;i++) ans[q[i].id]=(w[l]!=q[i].s||d[l]>q[i].c)?1:0;
    		return;
        }
    	int h1=L;
    	for(int i=L;i<=R;i++) if(q[i].r<=mid) tmp[h1++]=q[i];
    	int h2=h1;
    	for(int i=L;i<=R;i++) if(q[i].l<=mid&&q[i].r>mid) tmp[h2++]=q[i];
    	int h3=h2;
    	for(int i=L;i<=R;i++) if(q[i].l>mid) tmp[h3++]=q[i];
    	
    	for(int i=L;i<=R;i++) q[i]=tmp[i];
    	
    	Solve(l,mid,L,h1-1),Solve(mid+1,r,h2,h3-1);
    	
    	if(h2-h1<=0) return;
    	memset(f[mid],0x7f,sizeof(f[mid]));f[mid][w[mid]]=d[mid],f[mid][0]=0;
        for(int i=mid-1;i>=l;i--) for(int j=100;~j;j--){
    		f[i][j]=f[i+1][j];
    		if(j>=w[i]&&f[i+1][j-w[i]]<INF) f[i][j]=min(f[i][j],max(f[i+1][j-w[i]],d[i]));
    	}
    	
    	memset(g[mid+1],0x7f,sizeof(g[mid+1]));g[mid+1][w[mid+1]]=d[mid+1],g[mid+1][0]=0;
    	for(int i=mid+2;i<=r;i++) for(int j=100;~j;j--){
    		g[i][j]=g[i-1][j];
    		if(j>=w[i]&&g[i-1][j-w[i]]<INF) g[i][j]=min(g[i][j],max(g[i-1][j-w[i]],d[i]));
    	}
        
    	for(int i=h1;i<h2;i++){
    		for(int j=0;j<=q[i].s;j++) ans[q[i].id]=min(ans[q[i].id],max(f[q[i].l][j],g[q[i].r][q[i].s-j]));
    		if(ans[q[i].id]>q[i].c) ans[q[i].id]=1;else ans[q[i].id]=0;
    	}
    }
    int main(){
    //	freopen("in.in","r",stdin);
    //	freopen("out.out","w",stdout);
    	for(T=in();T--;){
    		n=in(),m=in();
    		for(int i=1;i<=n;i++) w[i]=in();for(int i=1;i<=n;i++) d[i]=in();
    		for(int i=1;i<=m;i++) q[i].l=in(),q[i].r=in(),q[i].c=in(),q[i].s=in(),q[i].id=i,ans[i]=INF;
    		Solve(1,n,1,m);
    		for(int i=1;i<=m;i++) putchar(ans[i]+'0');putchar('
    ');
    	}return 0;
    }
    

      

  • 相关阅读:
    【算法】数据结构
    【POJ】1222 EXTENDED LIGHTS OUT
    【BZOJ】1013 [JSOI2008]球形空间产生器sphere
    【有上下界网络流】【ZOJ】2314 Reactor Cooling
    【CODEVS】1281 Xn数列
    【POJ】3070 Fibonacci
    【CODEVS】3546 矩阵链乘法
    【BZOJ】1070: [SCOI2007]修车
    Quoit Design(hdu 1007)
    tree(poj 1741)
  • 原文地址:https://www.cnblogs.com/beiyuoi/p/5910559.html
Copyright © 2011-2022 走看看