zoukankan      html  css  js  c++  java
  • HZOI20190906模拟38 金,斯诺,赤

    题面:https://www.cnblogs.com/Juve/articles/11479415.html

    T1:高精度gcd,其实不用写高精度取模,gcd还有一种求法

    int gcd(int a,int b){
    	if(a==b) return a;
    	if(a%2==0&&b%2==0) return 2*gcd(a/2,b/2);
    	if(a%2==0) return gcd(a/2,b);
    	if(b%2==0) return gcd(a,b/2);
    	if(a<b) swap(a,b);
    	return gcd(a-b,b);
    }
    

    然后愉快地AC

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define int long long
    #define re register
    using namespace std;
    int t,la,lb,c[105];
    char a[105],b[105];
    struct bigint{
    	int m[105];
    	bigint(){memset(m,0,sizeof(m));}
    	inline friend void operator *= (bigint &a,re int b){
    		int x=0;
    		for(re int i=1;i<=a.m[0];i++){
    			re int y=a.m[i]*b+x;
    			a.m[i]=y%10;
    			x=y/10;
    		}
    		while(x){
    		    a.m[++a.m[0]]=x%10;
    		    x/=10;
    		}
    	}
    	inline friend void operator /= (bigint &a,re int b){
    		re int x=0;
    		for(re int i=a.m[0];i>=1;i--){
    			x+=a.m[i];
    			a.m[i]=x/b;
    			x%=b;
    			x*=10;
    		}
    		while(a.m[a.m[0]]==0&&a.m[0]>1) 
    			a.m[0]--;
    	}
    	inline friend bigint operator - (bigint a,bigint b){
    		bigint c;
    		re int i=1;
    		while((i<=a.m[0])||(i<=b.m[0])){
    			if(a.m[i]<b.m[i]){
    				a.m[i]+=10;
    				a.m[i+1]--;
    			}
    			c.m[i]=a.m[i]-b.m[i];
    			i++;
    		}
    		while(c.m[i]==0&&i>1)
    			i--;
    		c.m[0]=i;
    		return c;
    	}
    	inline friend bool operator >= (bigint a,bigint b){
    		if(a.m[0]>b.m[0]) return 1;
    		if(a.m[0]<b.m[0]) return 0;
    		for(int i=a.m[0];i>=1;--i){
    			if(a.m[i]==b.m[i]) continue;
    			return a.m[i]>b.m[i];
    		}
    		return 1;
    	}
    	inline friend bool operator == (bigint a,bigint b){
    		int p=a.m[0],q=b.m[0];
    		if(p!=q) return 0;
    		for(int i=1;i<=p;++i){
    			if(a.m[i]!=b.m[i]) return 0;
    		}
    		return 1;
    	}
    	inline friend void print(bigint a){
    		for(re int i=a.m[0];i>=1;i--)
    			printf("%lld",a.m[i]);
    		puts("");
    	}
    }n,m;
    bool judge(bigint a){
    	int p=a.m[1];
    	//cout<<p<<endl;
    	if(p%2==0) return 1;
    	return 0;
    }
    bool check(bigint a,bigint b){
    	//print(a),print(b);
    	if(a==b){
    		if(a.m[0]==1&&a.m[1]==1) return 1;
    		else return 0;
    	}
    	bool p=judge(a),q=judge(b);
    	//cout<<p<<' '<<q<<endl;
    	if(p&&q) return 0;
    	if(p){
    		a/=2;
    		return check(a,b);
    	}
    	if(q){
    		b/=2;
    		return check(a,b);
    	}
    	if(!(a>=b)) swap(a,b);
    	return check(a-b,b);
    }
    int gcd(int a,int b){
    	if(a==b) return a;
    	if(a%2==0&&b%2==0) return 2*gcd(a/2,b/2);
    	if(a%2==0) return gcd(a/2,b);
    	if(b%2==0) return gcd(a,b/2);
    	if(a<b) swap(a,b);
    	return gcd(a-b,b);
    }
    signed main(){
    	scanf("%lld",&t);
    	while(t--){
    		memset(n.m,0,sizeof(n.m));
    		memset(m.m,0,sizeof(m.m));
    		scanf("%s %s",a+1,b+1);
    		la=strlen(a+1),lb=strlen(b+1);
    		n.m[0]=la,m.m[0]=lb;
    		for(int i=1;i<=la;++i) n.m[la-i+1]=a[i]-'0';
    		for(int i=1;i<=lb;++i) m.m[lb-i+1]=b[i]-'0';
    		if(check(n,m)==1) puts("Yes");
    		else puts("No");
    	}
    	return 0;
    }
    

    T2:

    正解$O(n)$,数状数组卡常可A

    $sum_i$表示前缀和

    我们对于每一个i,求出$sum_i-sum_{j-1}>frac{i-j+1}{2}(j<i)$的数量

    然后就转化成了$2sum_i-i>2sum_{j-1}-(j-1)$,然后数状数组即可

    然后用总区间减去不合法的即可

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #define re register
    using namespace std;
    const int MAXN=5e6+5;
    int n,sum0[MAXN],sum1[MAXN],sum2[MAXN],sum[MAXN];
    char a[MAXN],ch;
    long long ans=0;
    struct BIT_tree{
    	int c[MAXN*3];
    	inline int lowbit(re int x){
    		return x&-x;
    	}
    	inline void add(re int pos){
    		//cout<<pos<<' '<<val<<endl;
    		while(pos<=2*n){
    			++c[pos];
    			pos+=lowbit(pos);
    			//cout<<pos<<endl;
    		}
    	}
    	inline int query(re int pos){
    		re int res=0;
    		while(pos>0){
    			res+=c[pos];
    			pos-=lowbit(pos);
    		}
    		return res;
    	}
    }tr[3];
    signed main(){
    	//freopen("ex4.in","r",stdin);
    	scanf("%d",&n);
    	scanf("%s",a+1);
    	for(re int i=1;i<=n;++i){
    		sum0[i]=sum0[i-1],sum1[i]=sum1[i-1],sum2[i]=sum2[i-1];
    		if(a[i]=='0') ++sum0[i];
    		if(a[i]=='1') ++sum1[i];
    		if(a[i]=='2') ++sum2[i];
    		tr[0].add(2*sum0[i-1]-i+n+2);
    		ans+=tr[0].query(2*sum0[i]-i+n);
    		tr[1].add(2*sum1[i-1]-i+n+2);
    		ans+=tr[1].query(2*sum1[i]-i+n);
    		tr[2].add(2*sum2[i-1]-i+n+2);
    		ans+=tr[2].query(2*sum2[i]-i+n);
    	}
    	printf("%lld
    ",(1ll*n*(n+1)/2)-ans);
    	return 0;
    }
    

    %%正解大佬gby

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #define lowbit(x) ((x)&(-(x)))
    #define N 5555555
    #define LL long long
    #define pre(i,j) pre[(i)+nn][j]
    #define tb(i,j) tb[(i)+nn][j]
    
    using namespace std;
    
    int nn,pre[2*N][3],tb[2*N][3];
    char arr[N];
    int dat[N][3];
    LL ans;
    int main(){
    	scanf("%d",&nn);
    	scanf("%s",arr+1);
    	for(int i=1;i<=nn;i++){
    		dat[i][0]=dat[i-1][0]+1;
    		dat[i][1]=dat[i-1][1]+1;
    		dat[i][2]=dat[i-1][2]+1;
    		dat[i][arr[i]-'0']-=2;
    	}
    	/*for(int i=0;i<=2;i++){
    		printf("%d:",i);
    		for(int j=1;j<=nn;j++)
    			cout<<dat[j][i]<<" ";
    		cout<<endl;
    		}*/
    	ans=(long long)nn*(nn+1)/2;
    	//cout<<ans<<endl;
    	pre(0,0)++,pre(0,1)++,pre(0,2)++;
    	tb(0,0)++ ,tb(0,1)++, tb(0,2)++;
    	static int lst[3];
    	for(int i=1;i<=nn;i++){
    		for(int k=0;k<=2;k++){
    			tb(dat[i][k],k)++;
    			if(dat[i][k]==lst[k]+1){				
    				pre(dat[i][k],k)=pre(lst[k],k)+tb(dat[i][k],k);
    			}
    			else {//dat[i][k]==lst[k]-1
    				pre(dat[i][k],k)=pre(dat[i][k]-1,k)+tb(dat[i][k],k);
    				pre(lst[k],k)=pre(dat[i][k],k)+tb(lst[k],k);
    			}
    			ans-=i+1-pre(dat[i][k],k);
    			//	cout<<k<<":"<<i+1-pre(dat[i][k],k)<<endl;
    		}
    		lst[0]=dat[i][0];
    		lst[1]=dat[i][1];
    		lst[2]=dat[i][2];
    		/*for(int i=0;i<=2;i++){
    			printf("%d:",i);
    			for(int j=-nn;j<=nn;j++)
    				cout<<pre(j,i)<<" ";
    			cout<<endl;
    			}*/
    	}
    	cout<<ans<<endl;
    }
    

    T3:

    wqs二分

    首先一个暴力dp:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define re register
    using namespace std;
    const int MAXN=100005;
    int n,a,b;
    double p[MAXN],q[MAXN],ans=0.0,f[2][605][605];
    inline double max(re double a,re double b){
    	return a>b?a:b;
    }
    signed main(){
    	while(~scanf("%d%d%d",&n,&a,&b)){
    		//memset(f,0,sizeof(f));
    		for(re int i=1;i<=n;++i) scanf("%lf",&p[i]);
    		for(re int i=1;i<=n;++i) scanf("%lf",&q[i]);
    		ans=0.0;
    		//f[0][0][0]=0;
    		memset(f[0],0,sizeof(f[0]));
    		for(re int i=1;i<=n;++i){
    			for(re int j=0;j<=min(a,n);++j){
    				for(re int k=0;k<=min(b,n);++k){
    				    f[i&1][j][k]=f[i&1^1][j][k];
    				    if(j!=0) f[i&1][j][k]=max(f[i&1][j][k],f[i&1^1][j-1][k]+p[i]);
    				    if(k!=0) f[i&1][j][k]=max(f[i&1][j][k],f[i&1^1][j][k-1]+q[i]);
    				    if(j!=0&&k!=0)
    				        f[i&1][j][k]=max(f[i&1][j][k],f[i&1^1][j-1][k-1]+p[i]+q[i]-p[i]*q[i]);
    				}
    			}
    		}
    		printf("%0.3lf
    ",f[n&1][a][b]);
    	}
    	return 0;
    }
    

    然后优化:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define re register
    #define eps 1e-8
    using namespace std;
    const int MAXN=100005;
    int n,a,b;
    double p[MAXN],q[MAXN],ans=0.0,l,r,L,R,f[MAXN],fa[MAXN],fb[MAXN];
    inline double max(re double a,re double b){
    	return a>b?a:b;
    }
    bool judge(double na,double nb){
    	memset(f,0,sizeof(f));
    	memset(fa,0,sizeof(fa));
    	memset(fb,0,sizeof(fb));
    	for(int i=1;i<=n;i++){
            f[i]=f[i-1],fa[i]=fa[i-1],fb[i]=fb[i-1];
            if(f[i-1]+p[i]>f[i]+na)
    			f[i]=f[i-1]+p[i]-na,fa[i]=fa[i-1]+1,fb[i]=fb[i-1];
            if(f[i-1]+q[i]>f[i]+nb)
    			f[i]=f[i-1]+q[i]-nb,fb[i]=fb[i-1]+1,fa[i]=fa[i-1];
            if(f[i-1]+p[i]+q[i]-p[i]*q[i]>f[i]+na+nb)
    			f[i]=f[i-1]+p[i]+q[i]-p[i]*q[i]-na-nb,fa[i]=fa[i-1]+1,fb[i]=fb[i-1]+1;
        }
    	return fb[n]>b;
    }
    bool check(double na){
    	L=0.0,R=1.0;
    	while(R-L>eps){
    		double mid=(L+R)/2.0;
    		if(judge(na,mid)) L=mid;
    		else R=mid;
    	}
    	judge(na,R);
    	return fa[n]>a;
    }
    signed main(){
    	while(~scanf("%d%d%d",&n,&a,&b)){
    		for(re int i=1;i<=n;++i) scanf("%lf",&p[i]);
    		for(re int i=1;i<=n;++i) scanf("%lf",&q[i]);
    		l=0.0,r=1.0;
    		ans=0.0;
    		memset(f,0,sizeof(f));
    		memset(fa,0,sizeof(fa));
    		memset(fb,0,sizeof(fb));
    		while(r-l>eps){
    			double mid=(l+r)/2.0;
    			if(check(mid)) l=mid;
    			else r=mid;
    		}
    		judge(r,R);
    		printf("%0.5lf
    ",f[n]+a*r+b*R);
    	}
    	return 0;
    }
    
  • 相关阅读:
    使用TransactionScope实现事务
    CYQ.Data 框架系列
    MVP
    DYCOM用于开发网络应用程序的通信部分功能的快速开发
    架构师要了解
    Entity Framework资源
    Sina Blogs
    关于TransactionScope出错:“与基础事务管理器的通信失败”的解决方法总结
    在西方的程序员眼里,东方的程序员是什么样的?
    net2.0事务学习
  • 原文地址:https://www.cnblogs.com/Juve/p/11479423.html
Copyright © 2011-2022 走看看