zoukankan      html  css  js  c++  java
  • 联合省选 2021

    卡牌游戏

    俩数组放在一起拍个序然后双指针扫一下即可。

    代码懒得写了。

    矩阵游戏

    Link

    考虑没有「其每个元素为大小不超过 ({10}^6) 的非负整数」这个限制怎么做,显然令 (a_{i,1}=a_{1,j};(1le ile n,;1le jle m)) 然后一个一个算其余的 (a_{i,j}) 即可。

    [left[egin{matrix}a_{1,1} & a_{1,2} & a_{1,3} & a_{1,4}\ a_{2,1} & a_{2,2} & a_{2,3} & a_{2,4}\ a_{3,1} & a_{3,2} & a_{3,3} & a_{3,4}\ a_{4,1} & a_{4,2} & a_{4,3} & a_{4,4}end{matrix} ight] ]

    我们得到了一个弱化版的答案,现在加上这个条件。考虑这个矩阵的第 (i) 行,若 (j) 为奇数加一个 (r_i),反之减一个 (r_i),列类似:

    [left[egin{matrix}a_{1,1}+r_1+c_1 & a_{1,2}-r_1+c_2 & a_{1,3}+r_1+c_3 & a_{1,4}-r_1+c_4\ a_{2,1}+r_2-c_1 & a_{2,2}-r_2-c_2 & a_{2,3}+r_2-c_3 & a_{2,4}-r_2-c_4\ a_{3,1}+r_3+c_1 & a_{3,2}-r_3+c_2 & a_{3,3}+r_3+c_3 & a_{3,4}-r_3+c_4\ a_{4,1}+r_4-c_1 & a_{4,2}-r_4-c_2 & a_{4,3}+r_4-c_3 & a_{4,4}-r_4-c_4end{matrix} ight] ]

    这样表示仍然是满足题意的。非常像差分约束,但是加法我们不会做,于是定义:

    [r_i'=egin{cases}r_i, &iequiv 1pmod 2\ -r_i & iequiv 0pmod 2end{cases}\ c_i'=egin{cases}c_i, &iequiv 0pmod 2\ -c_i & iequiv 1pmod 2end{cases} ]

    原矩阵变成了:

    [left[egin{matrix}a_{1,1}+r_1'-c_1' & a_{1,2}-r_1'+c_2' & a_{1,3}+r_1'-c_3' & a_{1,4}-r_1'+c_4'\ a_{2,1}-r_2'+c_1' & a_{2,2}+r_2'-c_2' & a_{2,3}-r_2'+c_3' & a_{2,4}+r_2'-c_4'\ a_{3,1}+r_3'-c_1' & a_{3,2}-r_3'+c_2' & a_{3,3}+r_3'-c_3' & a_{3,4}-r_3'+c_4'\ a_{4,1}-r_4'+c_1' & a_{4,2}+r_4'-c_2' & a_{4,3}-r_4'+c_3' & a_{4,4}+r_4'-c_4'end{matrix} ight] ]

    就可以差分约束了。

    显然每行/每列加减同一个数肯定能构造出有解的矩阵,因为如果有解,第一行、第一列对应的数一定是解中的数。

    #include<bits/stdc++.h>
    using namespace std;
    #define int long long
    const int N=1e6+10,M=2e6+10;
    int head[N],ver[M],nxt[M],tot=0,edge[M];
    void add(int x,int y,int z)
    {
    	ver[++tot]=y;
    	edge[tot]=z;
    	nxt[tot]=head[x];
    	head[x]=tot;
    }
    int dis[N],cnt[N];int n,m;
    bool vis[N],book[N];
    bool spfa(int S)
    {
    	queue<int> que;
    	dis[S]=0;
    	que.push(S);
    	while(!que.empty())
    	{
    		int x=que.front();que.pop();
    		book[x]=1;
    		vis[x]=0;
    		for(int i=head[x];i;i=nxt[i])
    		{
    			int y=ver[i],z=edge[i];
    			if(dis[x]+z>dis[y])
    			{
    				dis[y]=dis[x]+z;
    				if(++cnt[y]>n+m)return true;
    				if(!vis[y])
    				{
    					vis[y]=1;
    					que.push(y);
    				}
    			}
    		}
    	}
    	return false;
    }
    int a[310][310],b[310][310];
    void sol()
    {
    	memset(vis,0,sizeof(vis));
    	memset(dis,-0x3f,sizeof(dis));
    	memset(book,0,sizeof(book));
    	memset(cnt,0,sizeof(cnt));
    	memset(a,0,sizeof(a));
    	scanf("%lld%lld",&n,&m);
    	for(int i=1;i<n;i++)for(int j=1;j<m;j++)scanf("%lld",&b[i][j]);
    	for(int i=2;i<=n;i++)for(int j=2;j<=m;j++)a[i][j]=b[i-1][j-1]-a[i][j-1]-a[i-1][j]-a[i-1][j-1];
    	memset(head,0,sizeof(head));tot=0;
    	for(int i=1;i<=n;i++)
    	{
    		for(int j=1;j<=m;j++)
    		{
    			if((i+j)&1)add(i,j+n,-a[i][j]),add(j+n,i,a[i][j]-1e6);
    			else add(j+n,i,-a[i][j]),add(i,j+n,a[i][j]-1e6);
    		}
    	}
    	if(spfa(1)){puts("NO");return;}
    	for(int i=1;i<=n;i++)
    	{
    		for(int j=1;j<=m;j++)
    		{
    			if((i+j)&1)a[i][j]+=-dis[i]+dis[j+n];
    			else a[i][j]+=dis[i]-dis[j+n];
    		}
    	}
    	puts("YES");
    	for(int i=1;i<=n;i++)
    	{
    		for(int j=1;j<=m;j++)printf("%lld ",a[i][j]);
    		puts("");
    	}
    }
    signed main()
    {
    //	freopen("matrix5.in","r",stdin);
    	int T;
    	scanf("%lld",&T);
    	while(T--) sol();
    	return 0;
    }
    

    宝石

    (usim v) 的路径拆成 (usim operatorname{lca}(u,v))(含 (operatorname{lca}))和 (operatorname{lca}(u,v)sim v)(不含)。将 (w) 重新标号后第一段路径直接倍增即可,第二段路径二分之后再倍增即可。

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<queue>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    inline int read()
    {
        int x=0,f=1;char c=getchar();
        while(c<'0'||c>'9'){if(c=='0')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
        return x*f;
    }
    const int N=2e5+10,M=4e5+10;
    int head[N],ver[M],nxt[M],tot=0;
    void add(int x,int y)
    {
        ver[++tot]=y;
        nxt[tot]=head[x];
        head[x]=tot;
    }
    int pos[N],p[N],w[N];
    int n,m,c,t,rt[N];
    struct president_tree
    {
        int tot;
        struct node
        {
            int lc,rc,val;
            node(){lc=rc=val=0;}
        }t[N<<5];
        president_tree(){tot=0;}
        int build(int l,int r)
        {
            int p=++tot,mid=(l+r)/2;
            if(l==r) return p;
            t[p].lc=build(l,mid);
            t[p].rc=build(mid+1,r);
            return p;
        }
        int modify(int pre,int l,int r,int x,int d)
        {
            int p=++tot,mid=(l+r)/2;
            t[p]=t[pre];
            if(l==r){t[p].val=d;return p;}
            if(x<=mid)t[p].lc=modify(t[pre].lc,l,mid,x,d);
            else t[p].rc=modify(t[pre].rc,mid+1,r,x,d);
            return p;
        }
        int query(int p,int l,int r,int x)
        {
            if(l==r) return t[p].val;
            int mid=(l+r)/2;
            if(x<=mid)return query(t[p].lc,l,mid,x);
            else return query(t[p].rc,mid+1,r,x);
        }
    }T;
    int dep[N],fa[N][30];
    void bfs(int s)
    {
        queue<int> que;
        que.push(s);
        dep[s]=1;
        while(!que.empty())
        {
            int x=que.front();que.pop();
            for(int i=head[x];i;i=nxt[i])
            {
                int y=ver[i];
                if(dep[y])continue;
                dep[y]=dep[x]+1;
                fa[y][0]=x;
                for(int j=1;j<=t;j++)fa[y][j]=fa[fa[y][j-1]][j-1];
                que.push(y);
            }
        }
    }
    int lca(int x,int y)
    {
        if(dep[x]<dep[y])swap(x,y);
        for(int i=t;i>=0;i--)if(dep[fa[x][i]]>=dep[y])x=fa[x][i];
        if(x==y)return x;
        for(int i=t;i>=0;i--)if(fa[x][i]!=fa[y][i])x=fa[x][i],y=fa[y][i];
        return fa[x][0];
    }
    int col[N],g1[N][30],g2[N][30];
    void dfs1(int x)
    {
        int tmp=col[w[x]];
        if(w[x])col[w[x]]=x;
        if(w[x]!=c)g1[x][0]=col[w[x]+1];
        for(int i=1;i<=t;i++)g1[x][i]=g1[g1[x][i-1]][i-1];
        for(int i=head[x];i;i=nxt[i])
        {
            int y=ver[i];
            if(y==fa[x][0])continue;
            dfs1(y);
        }
        col[w[x]]=tmp;
    }
    void dfs2(int x)
    {
        int tmp=col[w[x]];
        if(w[x])col[w[x]]=x;
        if(w[x]&&w[x]!=1)g2[x][0]=col[w[x]-1];
        for(int i=1;i<=t;i++)g2[x][i]=g2[g2[x][i-1]][i-1];
        for(int i=head[x];i;i=nxt[i])
        {
            int y=ver[i];
            if(y==fa[x][0])continue;
            dfs2(y);
        }
        col[w[x]]=tmp;
    }
    void dfs(int x)
    {
        if(!w[x])rt[x]=rt[fa[x][0]];
        else rt[x]=T.modify(rt[fa[x][0]],1,c,w[x],x);
        for(int i=head[x];i;i=nxt[i])
        {
            int y=ver[i];
            if(y==fa[x][0])continue;
            dfs(y);
        }
    }
    void Sol()
    {
        int u=read(),v=read(),L=lca(u,v);
        u=T.query(rt[u],1,c,1);
        int ans1=0;
        if(dep[u]>=dep[L]) ans1=1;
        for(int i=t;i>=0;i--)if(dep[g1[u][i]]>=dep[L])ans1+=(1<<i),u=g1[u][i];
        if(ans1==c){printf("%d
    ",c);return;}
        int l=ans1+1,r=c,ans2=0;
        while(l<=r)
        {
            int mid=(l+r)/2;
            int x=T.query(rt[v],1,c,mid);
    //        printf("v=%d, mid=%d, x=%d
    ",v,mid,x);
            if(dep[x]<=dep[L]){r=mid-1;continue;}
            for(int i=0;i<=t;i++)if((mid-ans1-1)&(1<<i))x=g2[x][i];
            if(dep[x]>dep[L])l=mid+1,ans2=mid;
            else r=mid-1;
        }
        if(!ans2)printf("%d
    ",ans1);
        else printf("%d
    ",ans2);
    }
    int main()
    {
        n=read(),m=read(),c=read();
        rt[0]=T.build(1,c);
        t=(int)(log(n)/log(2))+1;
        for(int i=1;i<=c;i++)pos[p[i]=read()]=i;
        for(int i=1;i<=n;i++)w[i]=pos[read()];
        for(int i=1;i<n;i++){int u=read(),v=read();add(u,v),add(v,u);}
        bfs(1),dfs1(1),dfs2(1),dfs(1);
        int q=read();
        for(int i=1;i<=q;i++)Sol();
        return 0;
    }
    
  • 相关阅读:
    ASP.net 知识框架
    MD5验证用户登陆密码
    企业面试题汇总.net
    MD5 加密,AES加密,解密 方法
    我选择了学Python
    校内网的错误信息
    Gmail客户端详细架构之一
    UE
    Gmail客户端详细架构之二:象Gmail一样上传文件
    PATH OR FILE NOT FOUND 之 RTX51.LIB
  • 原文地址:https://www.cnblogs.com/juruo-zzt/p/14761519.html
Copyright © 2011-2022 走看看