Codeforces Round #305 (Div. 1) A,B,C,D题解

这次的A题750分啊...一眼看上去很简单的结果我房间基本团灭...细节处理太多了。

最后10分钟想到C怎么做了可是没来及码出来

----------------------------------------------------------------------------------------------------------------------------------------------------------------------

A.Mike and Frog

有两个东西。第一个初始高度为h1,第二个初始高度为h2

每过一秒,第一个的高度变为,第二个的高度变为 

问你何时第一个高度为a1且第二个高度为a2



一眼看上去就知道是找循环节。

找到循环节后如果两个都在循环节,得到同余方程可以暴力枚举m次来求解

如果有一个不在循环则判断这个到达目标时另一个是否也正好到达

如果都不在循环里那么就判断是否过了相同的时间到达目标即可

----------------------------------------------------------------------------------------------------------------------------------------------------------------------

B.Mike and Feet

有一个长度为n的序列。问你对于每个长度x,形成的所有数列的最小值的最大值是多少



我们可以先把所有数从大到小排序。每次加入一个数的时候在线段树中把那个数的位置+1,如果连续1的长度大于等于x则输出答案即可

----------------------------------------------------------------------------------------------------------------------------------------------------------------------

C.Mike and Foam

给你一个数列,有q个操作。每次对x位置的数进行操作。如果不在当前集合中则加入集合,在则删除。问每次操作后所有数中gcd为1的数有几对。

初始集合为空



这题涉及到了gcd。统计gcd为1的不太好统计,那么我们就统计不为1的

考虑加入一个数。因为每个数<=50W。所以一个数最多有7个质因数。即有2^7种可能与别的数形成gcd不为1。

考虑2^7的贡献,即为1个质因数的个数-2个+3个-4个……-7个

那么容斥一下就好了

可以提前预处理莫比乌斯函数,可以提前预处理莫比乌斯函数,然后记录前面出现过的所有不含相同



可以提前预处理莫比乌斯函数,然后记录前面出现过的所有不含相同因子的约数,然后枚举当前数不含有相同质因子的约数来更新答案,再用总数减一下即可

----------------------------------------------------------------------------------------------------------------------------------------------------------------------

D.Mike and Fish

给你一些坐标轴上的点(x,y),【x,y为整数】。让你给这些点红蓝染色。要求同一行或同一列的点红蓝个数之差小于等于1。输出一种染色方案


我们把这张图想成二分图。一边表示x一边表示y。对于每个点(x,y)即连一条x到y的边

那么问题转化成了给边染色。要求每个点的边红蓝个数之差小于1

如果每条边的度都为偶数,那么我们直接dfs,红蓝间隔染色。即可保证符合题目要求

如果有边的度数为奇数。那么把为奇数的边先染色,则可以保证个数之差小于1

记得染色结束就删边否则会TLE

----------------------------------------------------------------------------------------------------------------------------------------------------------------------

A.Mike and Frog

#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
using namespace std;
long long v1[1000001],v2[1000001];
int fx1[1000001],fx2[1000001];
int px[1000001];
int main()
{
	 int i;
     long long m;
     scanf("%I64d",&m);
     long long h1,a1,x1,y1,h2,a2,x2,y2;
     scanf("%I64d%I64d",&h1,&a1);
     scanf("%I64d%I64d",&x1,&y1);
     scanf("%I64d%I64d",&h2,&a2);
     scanf("%I64d%I64d",&x2,&y2);
     memset(v1,-1,sizeof(v1));
     memset(v2,-1,sizeof(v2));
     v1[h1]=0;
     fx1[0]=h1;
     h1=(x1*h1+y1)%m;
     int d=1;
     while(v1[h1]==-1)
     {
          v1[h1]=d;
          fx1[d]=h1;
          d++;
          h1=(x1*h1+y1)%m;
     }
     v2[h2]=0;
     fx2[0]=h2;
     h2=(x2*h2+y2)%m;
     int dt=1;
     while(v2[h2]==-1)
     {
          v2[h2]=dt;
          fx2[dt]=h2;
          dt++;
          h2=(x2*h2+y2)%m;
     }
     long long len1=d-v1[h1],len2=dt-v2[h2];
     if(v1[a1]<v1[h1]&&v2[a2]<v2[h2])
     {
     	  if(v1[a1]==v2[a2])
     	       printf("%I64d\n",v1[a1]);
     	  else
               printf("-1\n");
          return 0;
     }
     else if(v1[a1]<v1[h1])
     {
     	  if((v1[a1]-(v2[a2]-v2[h2]))%len2==0&&v1[a1]!=-1&&(v1[a1]-(v2[a2]-v2[h2]))>=0&&v1[a1]>=v2[h2])
     	       printf("%I64d\n",v1[a1]);
     	  else
               printf("-1\n");
          return 0;
     }
     else if(v2[a2]<v2[h2])
     {
     	  if((v2[a2]-(v1[a1]-v1[h1]))%len1==0&&v2[a2]!=-1&&(v2[a2]-(v1[a1]-v1[h1]))>=0&&v2[a2]>=v1[h1])
     	       printf("%I64d\n",v2[a2]);
     	  else
               printf("-1\n");
          return 0;
     }
     long long ans=0;
     if(v1[a1]<v2[a2])
     {
          h1=a1;
          for(i=1;i<=v2[a2]-v1[a1];i++)
               h1=(x1*h1+y1)%m;
          ans=v2[a2];
          int p=0;
          long long th1=h1;
          while(th1!=a1)
          {
               th1=(x1*th1+y1)%m;
               p++;
          }
          if(p==0)
          {
               printf("%I64d\n",ans);
               return 0;
          }
          else if(len1==len2)
          {
               printf("-1\n");
               return 0;
          }
          long long t=(x1*h1+y1)%m;
          for(i=1;i<=len1;i++)
          {
               px[i]=t;
               t=(x1*t+y1)%m;
		  }
		  t=px[len1];
		  int dd=len1;
		  int s=0;
		  while(t!=a1)
		  {
		       dd=(dd+len2-1)%len1+1;
		       t=px[dd];
		       ans+=len2;
		       s++;
		       if(s>m+1)
		       {
		            printf("-1\n");
		            return 0;
		       }
		  }
		  printf("%I64d\n",ans);
     }
     else
     {
          h2=a2;
          for(i=1;i<=v1[a1]-v2[a2];i++)
               h2=(x2*h2+y2)%m;
          ans=v1[a1];
          int p=0;
          long long th2=h2;
          while(th2!=a2)
          {
               th2=(x2*th2+y2)%m;
               p++;
          }
          if(p==0)
          {
               printf("%I64d\n",ans);
               return 0;
          }
          else if(len1==len2)
          {
               printf("-1\n");
               return 0;
          }
          long long t=(x2*h2+y2)%m;
          for(i=1;i<=len2;i++)
          {
               px[i]=t;
               t=(x2*t+y2)%m;
		  }
		  t=px[len2];
		  int dd=len2;
		  int s=0;
		  while(t!=a2)
		  {
		       dd=(dd+len1-1)%len2+1;
		       t=px[dd];
		       ans+=len1;
		       s++;
		       if(s>m+1)
		       {
		            printf("-1\n");
		            return 0;
		       }
		  }
		  printf("%I64d\n",ans);
     }
     return 0;
}



B.Mike and Feet

#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
using namespace std;
struct ask
{
	int a,p;
	bool operator<(ask b) const
	{
		return a>b.a;
	}
}t[200001];
int lt[200001],*const ltt=lt+10,rt[200001],*const rtt=rt+10;
int n;
inline void init()
{
	scanf("%d",&n);
	int i;
	for(i=0;i<n;i++)
	{
		scanf("%d",&t[i].a);
		t[i].p=i;
	}
	sort(t,t+n);
}
int find(int *arr,int a)
{
	if(arr[a]==a)
		return a;
	int r=find(arr,arr[a]);
	arr[a]=r;
	return r;
}
inline void solve()
{
	int pos=0;
	int i;
	for(i=0;i<n;i++)
	{
		lt[t[i].p]--;
		rt[t[i].p]++;
		int l=find(lt,t[i].p),r=find(rt,t[i].p);
		while(pos<=r-l-2)
		{
			if(pos)
				printf(" ");
			printf("%d",t[i].a);
			pos++;
		}
	}
}
int main()
{
    init();
    int i;
	for(i=-1;i<=n;i++)
		lt[i]=i;
	for(i=-1;i<=n;i++)
		rt[i]=i;
    solve();
	printf("\n");
	return 0;
}



C.Mike and Foam

#include<cmath>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
using namespace std;
long long s[500001];
long long mu[1000001],prime[1000001];
bool check[1000001]; 
long long mod=1000000007;
int tot;
inline void findmu()
{
     memset(check,false,sizeof(check));
     mu[1]=1;
     int i,j;
     for(i=2;i<=500000;i++)
     {
          if(!check[i])
          {
               tot++;
               prime[tot]=i;
               mu[i]=1;
          }
          for(j=1;j<=tot;j++)
          {
               if(i*prime[j]>500000)
                    break;
               check[i*prime[j]]=true;
               if(i%prime[j]==0)
               {
                    mu[i*prime[j]]=0;
                    break;
               }
               else
                    mu[i*prime[j]]=-mu[i];
          }
     }
}
long long xt[200001][128];
bool v[500001];
int a[200001];
int main()
{
     int n,q;
     scanf("%d%d",&n,&q);
     findmu();
     int i,j;
     for(i=1;i<=n;i++)
          scanf("%d",&a[i]);
     for(i=1;i<=n;i++)
     {
     	  if(a[i]==1)
     	       continue;
     	  if(mu[a[i]]!=0)
     	  {
     	       xt[i][0]++;
     	       xt[i][1]=a[i];
     	  }
          for(j=2;j<=sqrt(a[i]);j++)
          {
          	   if(a[i]%j==0)
          	   {
          	   	    if(mu[j]!=0)
          	   	    {
			             xt[i][0]++;
                         xt[i][xt[i][0]]=j;
                    }
                    int d=a[i]/j;
                    if(d!=j&&mu[d]!=0)
                    {
			             xt[i][0]++;
                         xt[i][xt[i][0]]=d;
                    }
			   }
          }
     }
     int x;
     long long ans=0;
     long long sum=0;
     for(i=1;i<=q;i++)
     {
          scanf("%d",&x);
          if(!v[x])
          {
          	   sum++;
               v[x]=true;
               for(j=1;j<=xt[x][0];j++)
               {
                    ans=(ans+mu[xt[x][j]]*s[xt[x][j]]);
                    s[xt[x][j]]++;
               }
          }
          else
          {
          	   sum--;
               v[x]=false;
               for(j=1;j<=xt[x][0];j++)
               {
                    s[xt[x][j]]--;
                    ans=(ans-mu[xt[x][j]]*s[xt[x][j]]);
               }
          }
          long long ts=(sum*(sum-(long long)1)/(long long)2-ans);
          printf("%I64d\n",ts);
     }
     return 0;
}



D.Mike and Fish

#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
using namespace std;
struct line
{
     int s,t;
     int x;
     int next;
     int la;
}a[800001];
int head[400001];
int edge;
inline void add(int s,int t,int x)
{
	 a[edge].next=head[s];
	 a[head[s]].la=edge;
	 head[s]=edge;
     a[edge].s=s;
     a[edge].t=t;
     a[edge].x=x;
}
bool v[400001];
int indeg[400001];
int c[400001];
int tot,p[400001];
inline void dfs(int d,int x)
{
	 if(indeg[d]==0)
	      return ;
     int i;
     for(i=head[d];i!=0;i=a[i].next)
     {
          int t=a[i].t,xt=a[i].x;
          if(!v[xt])
          {
          	   indeg[d]--;
          	   indeg[t]--;
               v[xt]=true;
               c[xt]=x;
               a[a[i].la].next=a[i].next;
               if(i==head[d])
                    head[d]=a[i].next;
               dfs(t,-x);
               break;
          }
          else
          {
               a[a[i].la].next=a[i].next;
               if(i==head[d])
                    head[d]=a[i].next;
          }
     }
}
int main()
{
     int n;
     scanf("%d",&n);
     int i;
     int x,y;
     for(i=1;i<=n;i++)
     {
          scanf("%d%d",&x,&y);
          y=y+200000;
          indeg[x]++;
          indeg[y]++;
          tot++;
          p[tot]=x;
          tot++;
          p[tot]=y;
          edge++;
          add(x,y,i);
          edge++;
          add(y,x,i);
     }
     sort(p+1,p+1+tot);
     for(i=1;i<=tot;i++)
          if(indeg[p[i]]%2==1)
               dfs(p[i],1);
     for(i=1;i<=tot;i++)
          dfs(p[i],1);
     for(i=1;i<=n;i++)
     {
          if(c[i]==1)
               printf("r");
          else
               printf("b");
     }
     printf("\n");
     return 0;
}


可以提前预处理莫比乌斯函数,然后记录前面出现过的所有不含相同
可以提前预处理莫比乌斯函数,然后记录前面出现过的所有不含相同
可以提前预处理莫比乌斯函数,然后记录前面出现过的所有不含相同
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值