传送门
题意
B.将cube顺序复原
C.无根转有根树,并且对于(除去顶点)的每棵子树,其顶点颜色相同
D.给出n个平行于坐标轴的边长为奇数的矩形,矩形接触而不覆盖,将其染色,接触矩形颜色不同,给出一种可行方案
E.给出n个模m的数(乱序),问是否构成等差数列,是则给出首项及方差,否则输出NO
题解
B.从两端往中间扫,复杂度(O(n))
C.引用renadeen的解释
I have a simpler solution. Take all edges that connect vertices of different colors. If all these edges have one common vertex — this vertex is the answer. Otherwise the answer is NO.
所以只要找到一个顶点能在所有不同颜色的边中即可
一种sample的解释
D.根据四色定理可知必存在满足情况
对于某一矩形来说,若不与其他矩形接触,则任意颜色即可;
若与其他矩形接触,可以发现,由于边长为(odd%=),对于左下角而言,其((x&1+y&1+1))必定不相同,可根据此来构造,引用ljh2000的话:
Consider a rectangle,we have know that rectangles cannot intersect,and all sides of the rectangles have odd length.As we all know,the Four color theorem,so it must have a solution.What we need to do is to find a solution to give a color to every rectangle.If the lower left quarter of the rectangle,((x1,y1)),so that we can know the situation of ((x1+odd,x2+odd)),we can confirm that we just need to color the rectangle according to its (x1) and (y1)'s parity.
E.参考ljh2000的blog
引用(ChamrAn)的代码(与blog方法不同)
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 100010;
int n,m,a[N],b[N];
int ans,ansd;
inline LL Pow(LL a,int x,int mod){
LL res=1;
for(;x;x>>=1,a=a*a%mod) if(x&1) res=res*a%mod;
return res;
}
void solve(int *a,int n){
int gap=a[1]-a[0],cnt=0;a[n]=-1;
for(int i=0;i<n;i++) if(binary_search(a,a+n,(a[i]+gap)%m)) cnt++;
int k=n-cnt,d= Pow(k,m-2,m) * gap % m ;
ans=-1;ansd=(m-d)%m;
for(int i=0;i<n;i++) if(!binary_search(a,a+n,(a[i]+d)%m))
if(ans==-1) ans=a[i]; else {ans=-1;return;}
}
int main()
{
scanf("%d%d",&m,&n);
for(int i=0;i<n;i++) scanf("%d",&a[i]);
if(n==1 || n==m) return printf("%d 1
",a[0]),0;
sort(a,a+n);
if(2*n<m) solve(a,n);
else{
int t=0;
for(int i=0;i<m;i++) if(!binary_search(a,a+n,i)) b[t++]=i;
solve(b,t);if(ans!=-1) (ans+=1ll*ansd*t%m)%=m;
}
if(ans==-1) printf("-1
");
else printf("%d %d
",ans,ansd);
return 0;
}
提供一种(divE)不同与(Editorial)的做法(来源于(quality))
检查所有的(d=a[i]-a[1]),并用(d)和(sum)求出首项(tmp),再求出所有项的平方和(ret), 与原来输入的数平方和比较,若相同,则用(d)和(tmp)求出所有的项,并(check), 若成功,则输出(d)和(tmp), 总共(check)次数不超过(2)次
In order to meet the conditions for which this algorithm can work, we consider only p which is odd and n<m-1. While there is no deterministic way for solving an arbitrary quadratic equation, it can easily be transformed into y^2 = d (mod p) where the Cipolla algorithm allows us to solve with approximately 1/2 probability for each random number. So, the expected value is 2. The overall complexity is O(n log n + k log p), where k is the number of tries in the Cipolla algorithm. It can be quite high for the problem conditions, so although there is a probability for failure, it is very small.((gsCEA))
Nice solution! And in fact, you can simply try all a[i]-a[1] as d and find x with x+(x+d)+...+(x+(n-1)d) equals to the sum of the elements. As you have said, there are at most two pairs (x,d) which satisfy x^2+(x+d)^2+...+(x+(n-1)d)^2 equals to the sum of square. So we can check these two pairs by brute force.
((quailty))
(若有错误轻喷)
附代码
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define ll long long
inline void read(int &x){x=0; char ch=getchar();while(ch<'0') ch=getchar();while(ch>='0'){x=x*10+ch-48; ch=getchar();}}
int m,n;
ll tmp,s[2]={0,0},b[100100],a[100100];
ll do_exp(int a,int p)
{
ll ret=1;
for(;p;p>>=1,a=1LL*a*a%m) if(p&1) (ret=ret*a)%=m;
return ret;
}
int main()
{
scanf("%d %d",&m,&n);
for(int i=1;i<=n;++i)
{
scanf("%lld",a+i);(s[0]+=a[i])%=m;(s[1]+=a[i]*a[i])%=m;
}
if(n==1) { printf("%lld 0
",a[1]);return 0; }
if(n==m) { puts("0 1");return 0; }
sort(a+1,a+1+n);
//printf("%lld %lld
",s[0],s[1]);
for(int i=2;i<=n;++i)
{
int d=(a[i]-a[1])%m;
tmp=(s[0]-1LL*n*(n-1)/2%m*d%m+m)%m*do_exp(n,m-2)%m;
//printf("tmp=%lld
",tmp);
ll ret=(1LL*n*tmp%m*tmp%m+1LL*n*(n-1)%m*tmp%m*d%m+1LL*(n-1)*n*(2*n-1)/6%m*d%m*d%m)%m;
//printf("ret=%lld
",ret);
if(ret==s[1])
{
b[1]=tmp;
for(int i=2;i<=n;++i) b[i]=(b[i-1]+d)%m;
sort(b+1,b+1+n);
//for(int i=1;i<=n;++i) printf("b[%d]=%d%c",i,b[i],i==n?'
':' ');
bool flag=1;
for(int i=1;i<=n;++i) flag&=(a[i]==b[i]);
if(flag) {printf("%lld %d
",tmp,d);return 0;}
}
}
puts("-1");
return 0;
}