• 8.5总结


    8.5总结

    得分

    100+85+60

    Rank 1~~

    终于做了一次人做的比赛

    T1

    题目大意

    给定一个n*m的矩阵,(x,y)的值为(x-1)*m+y。有k次修改操作,每次把一行或一列乘上一个系数y,求矩阵每个数的和

    n,m<=1000000;k<=100000

    正解

    一眼题

    首先,修改操作的顺序可以随便调换。

    对于每一列,它的和就是(S1*m+S2*i)*yi,这个S1和S2取决于对行的修改,并且对于每一列都不变

    第一行对S1的贡献是0*y1,第二行对S1的贡献是1*y2,第三行对S1的贡献是2*y3...以此类推

    第一行对S2的贡献是y1,第二行对S2的贡献是y2...以此类推

    T2

    题目大意


    正解

    维护一个jump[i]数组表示第1列第i行跳m步会跳会第一列哪一行。

    move的时候可以先跳到第一列,再m步m步跳找循环节

    难点就在于怎么维护jump[i]数组。

    我调了11个小时拿了15分

    以下的"-1""+1"可能指循环意义下的增减

    更新一个点(x,y)的时候,(x-1,y-1),(x,y-1)与(x+1,y-1)所能到达的第一列的节点可能发生变化,进而影响到第一列某些点的jump[i]。

    由于第一列能到达点(x,y)的点一定是一个连续的区间,所以维护区间的端点就可以了。

    但是有可能区间是[1~r]与[l~n],所以要特判。

    把l--,r++然后往回缩。

    如果l--,r++之后代表[1~n]又要特判

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define O3 __attribute__((optimize(3)))
    using namespace std;
    
    int n,m,Q,i,j,k,tot,ll,rr,lll,rrr,kk,rx,ry,bzz,ggg;
    int x,y,z,tox,toy,xx,yy,st,en;
    int a[2005][2005];
    int bz[2005],l[2005];
    char str[15];
    int jump[2005];
    
    O3 int read()
    {
    	int s=0;char ch=getchar();
    	while ((ch<'0')||(ch>'9'))
    	ch=getchar();
    	while ((ch>='0')&&(ch<='9'))
    	{
    		s=s*10+ch-'0';
    		ch=getchar();
    	}
    	return s;
    }
    
    O3 int in(int x,int l,int r)
    {
    	if (x==-1) return 0;
    	if (l<=r)
    	{
    		if ((x>=l)&&(x<=r)) return 1;
    	}
    	else
    	{
    		if ((x<=r)||(x>=l)) return 1;
    	}
    	return 0;
    }
    
    O3 int pre(int x)
    {
    	return (x+n-2)%n+1;
    }
    
    O3 int nex(int x)
    {
    	return x%n+1;
    }
    
    O3 int good(int x,int y)
    {
    	int tox,toy;
    	int xx,yy;
    	toy=yy=y%m+1;
    	tox=x;
    	xx=nex(x);
    	if (a[xx][yy]>a[tox][toy])
    		tox=xx;
    	xx=pre(x);
    	if (a[xx][yy]>a[tox][toy])
    		tox=xx;
    	return tox;
    }
    
    O3 void jump_to_end(int k)
    {
    	int tox,toy;
    	while (k--)
    	{
    		
    		toy=y%m+1;
    		tox=good(x,y);
    		
    		x=tox;y=toy;
    		if (y==1) break;
    	}
    }
    
    O3 int getsum(int l,int r)
    {
    	if (r>=l) return r-l+1;
    	else
    	{
    		return n-l+1+r;
    	}
    }
    
    O3 void update(int xx,int yy)
    {
    	int ll,rr,i,lll,rrr;
    	rx=x;ry=y;
    	x=xx;y=yy;
    	jump_to_end(m+1);
    	tox=x;
    	x=rx;y=ry;
    	
    	ll=rr=xx;
    	bzz=1;
    	if (yy==1)
    	{
    		yy=m+1;
    		jump[xx]=tox;
    		tox=xx;
    	}
    	for (i=yy-1;i>=1;i--)
    	{
    		lll=ll;
    		rrr=rr;
    		if (getsum(pre(lll),rrr)>=getsum(ll,rr)) lll=pre(lll);
    		if (getsum(lll,nex(rrr))>=getsum(ll,rr)) rrr=nex(rrr);
    		if (getsum(lll,rrr)==n)
    		{
    			if (ll<=rr)
    			{
    				if (ll>1)
    				{
    					if (ll>2)
    					{
    						if (!in(good(3,i),ll,rr))
    						{
    							lll=3;
    							rrr=2;
    						}
    					}
    					if (!in(good(2,i),ll,rr))
    					{
    						lll=2;
    						rrr=1;
    					}
    					if (!in(good(1,i),ll,rr))
    					{
    						lll=1;
    						rrr=n;
    					}
    					if (!in(good(n,i),ll,rr))
    					{
    						lll=1;
    						rrr=n;
    					}
    				}
    				if (rr<n)
    				{
    					if (rr<pre(n))
    					{
    						if (!in(good(pre(pre(n)),i),ll,rr))
    						{
    							lll=pre(pre(n));
    							rrr=pre(pre(pre(n)));
    						}
    					}
    					if (!in(good(pre(n),i),ll,rr))
    					{
    						lll=pre(n);
    						rrr=pre(pre(n));
    					}
    					if (!in(good(n,i),ll,rr))
    					{
    						lll=1;
    						rrr=n;
    					}
    					if (!in(good(nex(n),i),ll,rr))
    					{
    						lll=nex(n);
    						rrr=n;
    					}
    				}
    			}
    			else
    			{
    				if (ll==nex(nex(rr)))
    				{
    					if (!in(good(rr,i),ll,rr))
    					{
    						lll=rr;
    						rrr=pre(rr);
    					}
    					if (!in(good(nex(rr),i),ll,rr))
    					{
    						lll=nex(rr);
    						rrr=rr;
    					}
    					if (!in(good(nex(nex(rr)),i),ll,rr))
    					{
    						lll=nex(nex(rr));
    						rrr=nex(rr);
    					}
    				}
    				else
    				{
    					if (!in(good(rr,i),ll,rr))
    					{
    						lll=rr;
    						rrr=pre(rr);
    					}
    					if (!in(good(nex(rr),i),ll,rr))
    					{
    						lll=nex(rr);
    						rrr=rr;
    					}
    					if (!in(good(nex(nex(rr)),i),ll,rr))
    					{
    						lll=nex(nex(rr));
    						rrr=nex(rr);
    					}
    					if (!in(good(nex(nex(nex(rr))),i),ll,rr))
    					{
    						lll=nex(nex(nex(rr)));
    						rrr=nex(nex(rr));
    					}
    				}
    			}
    		}
    		while ((!in(good(lll,i),ll,rr)))
    		{
    			lll=nex(lll);
    			if (lll==nex(rrr))
    			{
    				bzz=0;
    				break;
    			}
    		}
    		while ((!in(good(rrr,i),ll,rr)))
    		{
    			rrr=pre(rrr);
    			if (rrr==pre(lll))
    			{
    				bzz=0;
    				break;
    			}
    		}
    		if (bzz==0) break;
    		ll=lll;
    		rr=rrr;
    		if (getsum(ll,rr)==n) break;
    	}
    	if (bzz==0) return;
    	if (ll<=rr)
    	{
    		for (i=ll;i<=rr;i++)
    		if ((yy!=1)||(i!=xx))
    		jump[i]=tox;
    	}
    	else
    	{
    		for (i=1;i<=rr;i++)
    		if ((yy!=1)||(i!=xx))
    		jump[i]=tox;
    		for (i=ll;i<=n;i++)
    		if ((yy!=1)||(i!=xx))
    		jump[i]=tox;
    	}
    }
    
    O3 int main()
    {
    	freopen("read.in","r",stdin);
    	freopen("jump.out","w",stdout);
    	scanf("%d%d",&n,&m);
    	for (i=1;i<=n;i++)
    	{
    		for (j=1;j<=m;j++)
    		{
    			a[i][j]=read();
    		}
    	}
    	for (i=1;i<=n;i++)
    	{
    		x=i; y=1;
    		jump_to_end(m+1);
    		jump[i]=x;
    	}
    	x=1;y=1;
    	scanf("%d",&Q);
    	while (Q--)
    	{
    		
    		scanf("%s",str+1);
    		if (str[1]=='m')
    		{
    			scanf("%d",&k);
    			kk=k-(m-y+1);
    			jump_to_end(k);
    			k=kk;
    			if (k<=0)
    			{
    				printf("%d %d
    ",x,y);
    				continue;
    			}
    			memset(bz,0,sizeof(bz));
    			tot=1;
    			l[1]=x;
    			bz[x]=1;
    			while (k>=m)
    			{
    				if (bz[jump[x]]==0)
    				{
    					bz[jump[x]]=bz[x]+1;
    					l[++tot]=jump[x];
    					x=jump[x];
    					k-=m;
    				}
    				else
    				{
    					en=bz[x];
    					st=bz[jump[x]];
    					k-=m;
    					break;
    				}
    			}
    			
    			if (k>=m)
    			{
    				x=l[st+(k/m)%(en-st+1)];
    				k=k%m;
    			}
    			jump_to_end(k);
    			printf("%d %d
    ",x,y);
    		}
    		else
    		{
    			scanf("%d%d%d",&xx,&yy,&z);
    			a[xx][yy]=z;
    			update(xx,(yy-2+m)%m+1);
    			update(pre(xx),(yy-2+m)%m+1);
    			update(nex(xx),(yy-2+m)%m+1);
    		}
    	}
    }
    

    小结

    1. 每道题都一定要做,都要拿分,多看数据的特殊性质。
    2. 时间安排要合理,有计划性
  • 相关阅读:
    延迟任务的实现方式
    brpc的安装20220620可用
    tmux和zsh的个性化配置针对无法连接外网的机器
    VimForCpp离线安装
    记录一个vim配置
    LeetCode No1051. 高度检查器
    LeetCode No890. 查找和替换模式
    LeetCode No63. 不同路径 II
    LeetCode No64. 最小路径和
    个人资料
  • 原文地址:https://www.cnblogs.com/leason-lyx/p/11306813.html
Copyright © 2020-2023  润新知