寒假集训day4

T1:致摸鱼两千年后的你

E[k]表示第k年后钱数的期望,E[0]=n

直接列出转移式
E[k+1]E[k]0.5考虑多一年,我们发现,E[k+1]的每种情况的概率是E[k]每种情况的概率*0.5
kSk+1SS1而每种情况之间是存在联系的,即第k年的每种情况,如S,第k+1年就存在S,S-1
E[k+1]=E[k]212所以E[k+1]=E[k]*2-\dfrac{1}{2}
52E[k]=2(2kE[0](2k11))+1最后用必修5的知识推一推,就可以得到2E[k]=2*(2^kE[0]-(2^{k-1}-1))+1

#include<bits/stdc++.h>
using namespace std;

typedef long long ll;
ll n,k,mod=1e9+7;
ll ksm(ll x,ll pow){
	ll ans=1,res=x%mod;
	while(pow){
		if(pow&1) ans=ans%mod*res%mod;
		res=res*res%mod;
		pow>>=1;
	}
	return ans%mod;
}
int main(){
	scanf("%lld%lld",&n,&k);
	n%=mod;
	if(k==0){
		printf("%lld",(n*2)%mod);
		return 0;
	}
	ll jc=ksm(2,k),jc2=ksm(2,k-1);
	//printf("check jc=%d jc2=%d\n",jc,jc2);
	ll ans=((((2*(jc*(n%mod)%mod)%mod-(2*jc2%mod%mod)+mod)%mod+2)%mod-1)%mod+mod)%mod;
	if(ans<0) ans+=mod;
	printf("%lld",ans);
}

T2:阿爽爱上了阿秦
dpvector本题我直接考虑了二维的dp,但发现最小值很难维护,所以我用vector,但是却爆了
mn其实正解也差不多,多枚举一维mn
dpkk这题用到了一个经典的dp优化套路,即要优化时,不要枚举k这一维,而考虑k是否有什么特殊性质,换一种方式枚举
kk并且可知k是单调的,所以k这一维可以不用枚举
On所以最后总的时间复杂度就是O(最大值n)
注意点:
1.memset1.这题时间卡得很死,所以不能用memset,只能在需要的时候赋初值
2.dp[i][0]1dp[i][0]12.dp[i][0]是1,因为没有初值,所以后面需要dp[i][0]转移,所以要赋为1

#include<bits/stdc++.h>
using namespace std;

typedef long long ll;
const int N=1010;
const ll MOD=998244353;
ll dp[N][N],ans=0,f[N][N];
int n,k,x[N];
int main(){
	scanf("%d%d",&n,&k);
	for(int i=1;i<=n;i++){
		scanf("%d",&x[i]);
	}
	sort(x+1,x+n+1);
	int mx=(x[n]-x[1])/(k-1);
	for(int mn=1;mn<=mx;mn++){
		int c=0;dp[0][0]=1;f[0][0]=1;
		for(int i=1;i<=n;i++)
		   {
		   	dp[i][0]=1;f[i][0]=(f[i-1][0])%MOD;
		while(x[i]-x[c+1]>=mn) c++;
		for(int j=1;j<=min(i,k);j++){
			dp[i][j]=(f[c][j-1]);
			f[i][j]=(f[i-1][j]+dp[i][j])%MOD;
		   }
	    }
	    ans=(ans+f[n][k])%MOD;
	}
	printf("%lld",ans);
}

T3:正反粒子湮灭
线看看数据范围,大概可以猜到用线段树,在仔细看看,是绝对值???!!!果断弃疗
2k线S(Sxor2k1,我们其实可以枚举每个属性的正负取值,建2^k颗线段树,再枚举S和(Sxor {2^k-1}),最后统计答案即可
由于我们发现绝对值如果反过来,那么取值一定没有原值大,所以不合法的方案一定比答案小,所以我们可以直接取最小值
00如果取相同的,答案即为0,答案一定大于等于0,所以不会产生矛盾

需要注意,线段树要开4倍空间

#include<bits/stdc++.h>
using namespace std;

typedef long long ll;
const int N=2e5+5;
const ll MAXN=1234567890000;
ll a[N][10];
int n,k,q;
ll ans,treex[N<<2][32],upda[10];
void push_up(int p,int type){
	treex[p][type]=max(treex[p<<1][type],treex[p<<1|1][type]);
}
void make_tree(int l,int r,int p,int type){
	if(l==r){
		int sum=0;
		for(int i=0;i<k;i++){
			if((1<<i)&type){
				sum+=a[l][i];
			}
			else sum-=a[l][i];
		}
		treex[p][type]=sum;
		return;
	}
	int mid=(l+r)>>1;
	make_tree(l,mid,p<<1,type);
	make_tree(mid+1,r,p<<1|1,type);
	push_up(p,type);
}
void uppdate(int l,int r,int p,int id,int num,int type){
	if(l==id&&r==id){
		treex[p][type]=num;
		return;
	}
	int mid=(l+r)>>1;
	if(id<=mid) uppdate(l,mid,p<<1,id,num,type);
	if(id>mid)  uppdate(mid+1,r,p<<1|1,id,num,type);
	push_up(p,type);
}
ll queryx(int l,int r,int p,int fs,int se,int type){
	if(fs<=l&&r<=se){
		return treex[p][type];
	}
	int mid=(l+r)>>1;
	ll mx=-MAXN;
	if(fs<=mid) mx=max(mx,queryx(l,mid,p<<1,fs,se,type));
	if(se>mid)  mx=max(mx,queryx(mid+1,r,p<<1|1,fs,se,type));
	return mx; 
}
int main(){
	scanf("%d%d",&n,&k);
	for(int i=1;i<=n;i++)
	for(int j=0;j<k;j++){
		scanf("%lld",&a[i][j]);
	}
	for(int i=0;i<(1<<k);i++){
		make_tree(1,n,1,i);
	}
	scanf("%d",&q);
	while(q--){
		int tp;
		scanf("%d",&tp);
		if(tp==1){
			int ai;
			scanf("%d",&ai);
			for(int i=0;i<k;i++){
				scanf("%lld",&upda[i]);
			}
			for(int i=0;i<(1<<k);i++){
				int sum=0;
				for(int j=0;j<k;j++){
					if((1<<j)&i) sum+=upda[j];
					else sum-=upda[j];
				}
				uppdate(1,n,1,ai,sum,i);
			}
		}
		if(tp==2){
			int l,r;
			scanf("%d%d",&l,&r);
			ans=0;
			for(int S=0;S<(1<<k);S++)
			{
			int T=S^((1<<k)-1);
			ll ans1=queryx(1,n,1,l,r,S),ans2=queryx(1,n,1,l,r,S^((1<<k)-1));
			ans=max(ans1+ans2,ans);
		    }
			printf("%lld\n",ans); 
		}
	}
}
发布了88 篇原创文章 · 获赞 5 · 访问量 1810
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览