• 校内模拟赛划水报告(9.9,9.11)


    D1T1:

    由于两个数在加小于min(lowbit(x),lowbit(y))的数对他们的奇偶性不影响

    所以直接暴力跳,lowbit到底,最后是nlogn^3???

    #include<cstdio>
    #include<algorithm>
    #define int long long
    using namespace std;
    int a[100010];
    int lowbit(int x)
    {
    	return x&(-x);
    }
    int check(int x)
    {
        int ans=0; 
    	while(x) 
    	{
    		x-=lowbit(x);
    		ans++; 
    	}
    	return ans;
    }
    bool cmp(int x,int y)
    {
    	while((check(x)&1)==(check(y)&1))
    	{
    		int ans=min(lowbit(x),lowbit(y));
    		x+=ans; 
    		y+=ans;
    	}
    	if(check(x)&1) return 0;
    	else return 1;
    }
    signed main()
    {
    	int n;
    	scanf("%lld",&n);
    	for(int i=1;i<=n;i++)	
    	scanf("%lld",&a[i]);
    	sort(a+1,a+n+1,cmp);
    	for(int i=1;i<=n;i++)	
    	printf("%lld ",a[i]);
    	return 0;
    }
    

      D1T2:直接二分天数然后暴力check即可

    #include<cstdio>
    #include<algorithm>
    #define int long long
    using namespace std;
    int a[100010],b[100010],c[100010],n;
    int check(int x)
    {
        int ans=0;
        for(int i=1;i<=n;i++)
        {
            if(a[i]-b[i]*x>0)
    		ans+=max(0ll,(a[i]-b[i]*x-1)/c[i]+1);
        }
        if(ans<=x) return 1;
        else return 0;
    }
    signed main()
    {
       
        scanf("%lld",&n);
        int mmin=99999999999ll;
        int mmax=-1;
        for(int i=1;i<=n;i++)
        {
            scanf("%lld%lld%lld",&a[i],&b[i],&c[i]);
            int cnt=(a[i]-1)/b[i]+1;
            mmin=min(mmin,cnt);
            mmax=max(mmax,cnt);
        }
        int l=0,r=mmax;
        while(l<r)
        {
            int mid=(l+r)/2;
            if(check(mid))
            {
                r=mid;
            }
            else
            {
                l=mid+1;
            }
        }
        printf("%lld",l);
        return 0;
    }
    

      D1T3:枚举第k条边是什么然后对每一条边的边权=max(e[i].v-V,0)然后再跑单源最短路 最后答案+V*k即可

    #include<cstdio>
    #include<cstring>
    #include<queue>
    #define int long long
    using namespace std;
    int n,m;
    int k,s,t;
    struct edge
    {
    	int v,last,w;
    }e[1000010],e2[1000010];
    int in[1000010],cnt=0;
    void addedge(int x,int y,int z)
    {
    	e2[++cnt].v=y;
    	e2[cnt].w=z;
    	e2[cnt].last=in[x];
    	in[x]=cnt;
    }
    const int inf=99999999999ll;
    struct node
    {
    	int dist,pos;
    	bool operator <(const node &x)const
        {
            return x.dist<dist;
        }
    };
    priority_queue<node> q;
    int dis[1000010];
    bool vis[1000010];
    int dijkstra()
    {
    	int i,x,y;
    	node tmp;
    	for(int i=1;i<=n;i++)
    	{
    		vis[i]=0;
    		dis[i]=inf;
    	}
    	dis[s]=0;
    	q.push((node){0,s});
    	while(!q.empty())
    	{
    		tmp=q.top();q.pop();
    		x=tmp.pos;
    		if(vis[x]!=0)continue;
    		vis[x]=1;
    		for(i=in[x];i;i=e[i].last)
    		{
    			y=e[i].v;
    			if(dis[y]>dis[x]+e[i].w)
    			{
    				dis[y]=dis[x]+e[i].w;
    				if(vis[y]==0)
    				q.push((node){dis[y],y});
    			}
    		}
    	}
    	return dis[t];
    }
    signed main()
    {
    	int x,y,v;
        int ans=inf;	
    	scanf("%lld%lld%lld%lld%lld",&n,&m,&k,&s,&t);
    	for(int i=1;i<=m;i++)
    	{
    		scanf("%lld%lld%lld",&x,&y,&v);
    		addedge(x,y,v);
    	}
    	memcpy(e,e2,sizeof(e2));
    	for(int i=1;i<=m;i++)
    	{
    		for(int j=1;j<=m;j++) 
    		e[j].w=max(e2[j].w-e2[i].w,0ll);
    		ans=min(ans,dijkstra()+e2[i].w*k);
    	}
    	printf("%lld",ans);
    	return 0;
    }
    

      D2T1:有一条线交换两个数即可,最后考虑如果交换成顺序就说明这条横线必须取,求出为逆序对即可

    #include<cstdio>
    #define ing long long
    using namespace std;
    int n,m;
    int a[1000010];
    int b[1000010];
    int lowbit(int k)
    {
        return k&(-k);
    }
    void add(int x)
    {
    	while(x<=n)
    	{
    		b[x]+=1;
    		x+=lowbit(x);
    	}
    }
    int count(int x)
    {
    	int sum=0;
    	while(x!=0)
    	{
    		sum+=b[x];
    		x-=lowbit(x);
    	}
    	return sum;
    }
    signed main()
    {
    	//freopen("permutation.in","r",stdin);
    	//freopen("permutation.out","w",stdout);
    	int x;
    	scanf("%lld%lld",&n,&m);
    	for(int i=1;i<=n;i++) 
    	a[i]=i;
    	for(int i=1;i<=m;i++)
    	{
    		scanf("%lld",&x);
    		int temp=a[x];
    		a[x]=a[x+1];
    		a[x+1]=temp;
    	}
    	for(int i=1;i<=n;i++)
        printf("%lld ",a[i]);
        printf("
    ");
        int cnt=0;
        for(int i=1;i<=n;i++)
        {
        	add(a[i]);
        	cnt+=i-count(a[i]);
        }
        printf("%lld",cnt);
        return 0;
    }
    

      D2T2:

    先跑最小生成树,如果有边答案就是这个最小生成树,反之加边,并用这个遍替换掉最大的遍,用LCA倍增求解即可

    #include<cstdio>
    #include<algorithm>
    #define int long long
    using namespace std;
    int n,m,f[400050][30],cnt,head[400050],fa[400050],dep[400050],vis[400050];
    int ans,o[400050],lg[400050];
    int mmax[400050][30];
    struct node
    {
    	int f,t,v,id;
    }a[400050<<1];
    
    struct Node
    {
    	int v,val,nex;
    }e[400050<<1];
    int find(int x)
    {
    	return fa[x]==x?x:fa[x]=find(fa[x]);
    }
    inline void add(int u,int v,int w)
    {
    	cnt++;
    	e[cnt].v=v;
    	e[cnt].val=w;
    	e[cnt].nex=head[u];
    	head[u]=cnt;
    }
    void dfs(int cur,int faa)
    {
    	int i;
    	dep[cur]=dep[faa]+1;
    	f[cur][0]=faa;
    	for(i=1;(1<<i)<=dep[cur];i++)
    	f[cur][i]=f[f[cur][i-1]][i-1],mmax[cur][i]=max(mmax[cur][i-1],mmax[f[cur][i-1]][i-1]);;
    	for(i=head[cur];i;i=e[i].nex)
    	{
    		int p=e[i].v;
    		if(p==faa) continue;
    		if(dep[p]) continue;
    		f[p][0]=cur;
    		mmax[p][0]=e[i].val;
    		dfs(p,cur);
    	}
    }
    int lca(int x,int y)
    {
    	int i,temp;
    	int ans=0;
    	if(dep[x]<dep[y])
    	{
    		temp=x;x=y;y=temp;
    	}
        for(int i=lg[dep[x]];i>=0;i--)
    		if(dep[f[x][i]]>=dep[y])
    		{
    			ans=max(ans,mmax[x][i]);
    			x=f[x][i];
    		}
    	if(x==y)return ans;
    	for(i=lg[dep[x]];i>=0;i--)
    	{
    		if(f[x][i]!=f[y][i])
    		{
    			ans=max(ans,max(mmax[x][i],mmax[y][i]));
    			x=f[x][i];
    			y=f[y][i];
    		}
    	}
    	ans=max(ans,max(mmax[x][0],mmax[y][0]));
    	return ans;
    }
    bool cmp(node x,node y)
    {
    	return x.v<y.v;
    }
    bool cmp1(node x,node y)
    {
    	return x.id<y.id;
    }
    signed main()
    {
    	scanf("%lld%lld",&n,&m);
    	for(int i=1;i<=n;i++) 
    	fa[i]=i;
    	for(int i=1;i<=m;i++)
    	{
    		scanf("%lld%lld%lld",&a[i].f,&a[i].t,&a[i].v);
    		a[i].id=i;
    	}
    	sort(a+1,a+1+m,cmp);
    	int tot=0;
    	for(int i=1;i<=m;i++)
    	{
    		int xx=find(a[i].f);
    		int yy=find(a[i].t);
    		if(xx==yy) continue;
    		ans+=(int)a[i].v;
    		fa[xx]=yy;tot+=1;
    		vis[a[i].id]=1;
    		add(a[i].f,a[i].t,a[i].v);
    		add(a[i].t,a[i].f,a[i].v);
    		if(tot>=n-1)break;
    	}
    	for(int i=1;i<=n;i++)
    	lg[i]=lg[i-1]+(1<<lg[i-1]==i);
    	dfs(1,0);
    	sort(a+1,a+1+m,cmp1);
    /*	for(int i=1;i<=m;i++)
    	printf("%lld
    ",lca(a[i].f,a[i].t)); */
    	for(int i=1;i<=m;i++)
    	{
    		if(vis[a[i].id])
    		printf("%lld
    ",ans);
    		else printf("%lld
    ",(ans+a[i].v-lca(a[i].f,a[i].t)));
    	}
    	return 0;
    }
    

      D2T3:考虑最后满足偶数,所以一直01异或满足最后是0即可,我们折半搜索,最后合并时查出值相等的最大值(因为用的map最后用了各种卡常才过了最后一个点。。。。)

    #pragma GCC optimize("O3")
    #pragma GCC optimize("Ofast,no-stack-protector")
    #pragma GCC optimize("Ofast")
    #pragma GCC target("sse3","sse2","sse")
    #pragma GCC target("avx","sse4","sse4.1","sse4.2","ssse3")
    #pragma GCC target("f16c")
    #pragma GCC optimize("inline","fast-math","unroll-loops","no-stack-protector")
    #pragma GCC diagnostic error "-fwhole-program"
    #pragma GCC diagnostic error "-fcse-skip-blocks"
    #pragma GCC diagnostic error "-funsafe-loop-optimizations"
    #pragma GCC diagnostic error "-std=c++14"
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<unordered_map>
    #include<cctype>
    using namespace std;
    int n,a[1010],ans2,stk[1000010],tail;
    long long ans1;
    unordered_map<long long,int> m1,m2,vis,q1,q2;
    char s[1010];
    int read()
    {
      int f=1,x=0;
      char ch=' ';
      for(;!isdigit(ch);ch=getchar())if(ch=='-')f*=-1;
      for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';
      return f*x;
    }
    int main()
    {
    	n=read();
    	for(int i=1;i<=n;i++)
    	{
    		scanf("%s",s);
    		int len=strlen(s);
    		for(int j=0;j<len;++j) 
    		a[i]=a[i]^(1<<(s[j]-'a'));
    	}
    	for(int i=0;i<(1<<(n/2));i++)
    	{
    		int res1=0,res2=0,num=0;
    		for(int j=1,u=i;j<=n/2;++j,u>>=1) 
    		if(u&1) 
    		{
    			res1=res1^a[j];
    			res2=res2^a[j+n/2];
    			num++;
    		}
    		m1[res1]++;
    		q1[res1]=max(num,q1[res1]);
    		m2[res2]++;
    		q2[res2]=max(num,q2[res2]);
    		if(!vis[res1]) 
    		{
    	    	vis[res1]=1;
    			stk[++tail]=res1;	
    		}
    	}
    	for(int i=1;i<=tail;i++)
    	{
    		int res=stk[i];
    		ans1+=1ll*m1[res]*m2[res];
    		vis[res]=1;
    		if((m1[res]==0||m2[res]==0)&&res!=0) continue;
    		ans2=max(ans2,q1[res]+q2[res]);
    	}
    	printf("%lld %d",ans1-1,ans2);
    	return 0;
    }
    

      

  • 相关阅读:
    常用分页插件
    sessionStorage二种存值取值的方法
    $(this).index()与$(obj).index(this)的区别
    每次移1px的无缝轮播图
    为什么全局变量在赋值之前调用会报错
    Number()、parseInt()和parseFloat()的区别
    JSON.parse()与JSON.stringify()
    HDU
    出现负数的01背包问题
    HDU
  • 原文地址:https://www.cnblogs.com/ninelifecat/p/11521965.html
Copyright © 2020-2023  润新知