Day1 模拟赛 题解

T1:首先你要发现,对于任意一个奇数i,i xor (i-1)=1;

   那么我们可以将答案转化为统计有多少个1相互异或起来;

   所以答案就那么几种;

  如果你用的数位DP,只能说明你太高估day1T1了;

  

#include <bits/stdc++.h>
using namespace std;
long long l,r,ans1,ans2;
int main ()
{
	int t;
	cin>>t;
	while(t--){
	cin>>l>>r;
	if(l>r) swap(l,r);
	--l;
	ans1=0;
	ans2=0;
	if(l&1)
	{
		long long tmp=l/2;
		if(tmp&1){
			ans1^=0;
		}
		else{
			ans1^=1;
		}
	}
	else{
		ans1^=l;
		--l;
		long long tmp=l/2;
		if(tmp&1){
			ans1^=0;
		}
		else{
			ans1^=1;
		}
	}
	if(r&1)
	{
		long long tmp=r/2;
		if(tmp&1){
			ans2^=0;
		}
		else{
			ans2^=1;
		}
	}
	else{
		ans2^=r;
		--r;
		long long tmp=r/2;
		if(tmp&1){
			ans2^=0;
		}
		else{
			ans2^=1;
		}
	}
	cout<<(ans1^ans2)<<endl;
	}
}

 

T2:

 

#include <iostream>
#include <cstdio>
#pragma GCC optimize(2)
using namespace std;
int n,m,p;
struct littlestar{
	int to;
	int nxt;
	int w;
}star[10300000];
int head[10300000],cnt;
void add(int u,int v,int w)
{
	star[++cnt].to=v;
	star[cnt].w=w;
	star[cnt].nxt=head[u];
	head[u]=cnt;
}
int floor,tot;
int have[20];
int ans=999999999;
int dis[10300000],vis[10300000],q[10300000];
void spfa()
{
	for(register int i=1;i<=tot;i++)
	{
		dis[i]=999999999;
	}
	dis[1]=0;
	vis[1]=1;
	int h=1,t=1;
	q[1]=1;
	while(h<=t){
		int u=q[h];
		for(register int j=head[u];j;j=star[j].nxt){
			int v=star[j].to;
			if(dis[v]>dis[u]+star[j].w){
				dis[v]=dis[u]+star[j].w;
				if(!vis[v]){
					q[++t]=v;
					vis[v]=1;
				}
			}
		}
		vis[u]=0;
		++h;
	}
}
int main ()
{	
    //freopen("library.in","r",stdin);
	cin>>n>>m>>p;
	floor=1<<p;	
	tot=n*floor;
	for(register int i=1;i<=m;i++){
		int x,y,z;
		scanf("%d%d%d",&x,&y,&z);
		for(register int j=0;j<floor;j++){
			add(n*j+x,n*j+y,z);
			add(n*j+y,n*j+x,z);
		}	
	}		
	for(register int k=1;k<=p;k++){
		int x,u,v,w;
		scanf("%d%d%d%d",&x,&u,&v,&w);
		for(register int i=0;i<floor;i++){
			for(register int j=1;j<=p;j++){
				if(i&(1<<(j-1))){
					have[j]=1;
				}
		 		else have[j]=0;
			}
			if(have[k]==1){
				add(n*i+u,n*i+v,w);
				add(n*i+v,n*i+u,w);
			}
			int tmp=i^(1<<(k-1));
			add(n*tmp+x,n*i+x,0);
	 	}
	}
	spfa();
	for(register int i=0;i<floor;i++){
		ans=min(ans,dis[i*n+n]);
	}
	cout<<ans<<endl;
}

 T3:

.使DPDPf[i]ig[i]if[i]f[i][1,i]jjig[j]()f[i]=f[j]+i(j+1)sum[i]g[i]=sum[i]sum[j]便N^2g[i]sum[i]sum[j]

 

#include<cstdio>
#include<iostream>
#pragma GCC optimize(2)
using namespace std;
int n,head,tail=1;
long long f[5000010],pre[5000010],sum[5000010],q[5000010];
int main()
{
    scanf("%d",&n);
    for(register int i=1;i<=n;++i)
    {
        int x;
        scanf("%d",&x);
        sum[i]=sum[i-1]+x;
    }
    for(register int i=1;i<=n;++i) 
    {
        while(head+1<tail&&sum[i]-sum[q[head+1]]>=pre[q[head+1]])
            ++head;
        f[i]=f[q[head]]+i-q[head]-1;
        pre[i]=sum[i]-sum[q[head]];
        while(head<tail&&sum[q[tail-1]]+pre[q[tail-1]]>sum[i]+pre[i])
            --tail;
        q[tail++]=i;
    }
    cout<<f[n];
    return 0;
}

 

posted @ 2019-10-29 17:00  神之右大臣  阅读(213)  评论(0编辑  收藏  举报