题目链接

感觉这样的题真的称得上是鬼斧神工啊,\(\text{OI}\)中能多一些这样的题目就太好了。

题意:

有一个二维的三角坐标系,大概如图所示(图是从atcoder里偷下来的):

坐标系上的每个整点处都有一盏灯,初始时只有一盏灯亮着。每次可以选择三个整点\((x,y)\),\((x,y+1)\),\((x+1,y)\)(即一个底边向下的正三角形),将这三盏灯的开关状态反转。现在给出若干次反转操作后所有亮着的\(n\)盏灯的坐标,求最初亮着的是哪一盏灯。\(n\leq 10^4\),\(-10^{17}\leq 坐标\leq 10^{17}\)。

题解:

我们考虑将从某一盏灯开始,不断通过向下反转将在\(y=c\)上的灯转移到\(y=c-1\)上。可以发现如果我们从\((0,0)\)开始向下转移\(c\)次,每一行的亮灯状态就是帕斯卡三角在模\(2\)意义下的结果,结合卢卡斯定理,可以发现\(y=-c\)上只有满足\(0\leq x\leq c\)且\(x\subseteq c\)的\((x,-c)\)是亮的。那么不难发现此时\((0,-c)\)和\((c,-c)\)一定是亮的,于是我们只要将所有亮着的灯向下转移到同一条足够低的直线上,再计算出这条直线上亮着的灯中最左端和最右端的点,就可以知道原来的点是什么。

说的好听,怎么计算左右端点呢?

我们先来研究一下帕斯卡三角在模\(2\)意义下有什么性质。如果我们将模\(2\)余\(1\)的点看作黑点,否则看作白点,那么帕斯卡三角是长这样的(偷自维基百科):

可以发现这是一个类似分形的结构,同时每一个三角形的边长都是\(2^k\)。那么考虑从这一行的任意一个亮着的\((x,y)\)开始向右移动,对于\(k=60,59,\dots,0\),如果\((x,y+2^k)\)是亮着的,那么移动到\((x,y+2^k)\),这相当于移动至右边的一个同构三角形的等价位置上。可以证明这一定可以移动到右端点。左端点也是类似的。判断一个点是否是亮着的也很简单,只需要\(O(n)\)扫描每个点即可。

于是我们得到了一个优秀的\(O(n\log MAX)\)的做法,其中\(MAX\)表示坐标范围。假的。

上面这个做法的问题在于我们无法快速找到一行中的一个会亮着的点!那么怎么高效的找到一个呢?

再考虑帕斯卡三角形的一个性质:对于第\(n\)行,对于\(k=0,1,2\),至少存在一个\(k\)使得\(\sum_{x\equiv k(\bmod\ 3)}{n\choose x}\equiv 1(\bmod \ 2)\),由归纳法保留上一行模\(3\)的和数组向下转移即可证明。假设我们可以在很快的时间里计算对于\(l\leq x\leq r\)且\(x\equiv k(\bmod\ 3)\)的\(x\),\((x,-c)\)是亮着的点数是奇数还是偶数,那么就可以通过二分的方法,每次选择点数是奇数的那一半继续做即可。由于左右两边的总点数是奇数因此这一半是一定存在的。

考虑怎么解决这个问题,显然在模\(2\)下每个点可以分开计算。那么对每个点考虑数位\(dp\),状态只需要记已经确定了几位,是否受数位的限制以及当前数在模\(3\)意义下余多少即可,结合卢卡斯定理可以设计转移。这么做复杂度是\(O(n\log MAX)\)的,结合二分,我们可以在\(O(n\log^2 MAX)\)的时间内找到一个亮着的点。于是我们就在\(O(n\log^2 MAX)\)的时间内解决了问题。

代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<utility>
using std::max;
using std::min;
using std::pair;
using std::make_pair;
typedef long long ll;
const int N=1e4+5;
int n;
ll x[N],y[N];
int res[3];
int dp[64][2][3];
inline void calc(ll c,ll x,ll y,ll r)
{
ll n=x-c;
register int i,j,k;
r-=y;
if(r<0)
return res[0]=res[1]=res[2]=0,void();
memset(dp,0,sizeof(dp));
dp[63][1][0]=1;
for(i=63;i>0;i--)
if(!(n>>(i-1)&1))
{
for(j=0;j<3;j++)
{
if(dp[i][0][j])
dp[i-1][0][(j*2)%3]^=1;
if(dp[i][1][j])
{
if(r>>(i-1)&1)
dp[i-1][0][(j*2)%3]^=1;
else
dp[i-1][1][(j*2)%3]^=1;
}
}
}
else
{
for(j=0;j<3;j++)
{
if(dp[i][0][j])
{
dp[i-1][0][(j*2)%3]^=1;
dp[i-1][0][(j*2+1)%3]^=1;
}
if(dp[i][1][j])
{
if(r>>(i-1)&1)
dp[i-1][0][(j*2)%3]^=1,dp[i-1][1][(j*2+1)%3]^=1;
else
dp[i-1][1][(j*2)%3]^=1;
}
}
}
y=(y%3+3)%3;
res[y]=dp[0][0][0]^dp[0][1][0];
res[(y+1)%3]=dp[0][0][1]^dp[0][1][1];
res[(y+2)%3]=dp[0][0][2]^dp[0][1][2];
return;
}
int lres[3],rres[3],mres[3];
inline ll epc(ll c)
{
int k;
ll l=-1000000000000000000ll,r=1000000000000000000ll,mid;
register int i;
rres[0]=rres[1]=rres[2]=0;
for(i=1;i<=n;i++)
{
calc(c,x[i],y[i],r);
rres[0]^=res[0];rres[1]^=res[1];rres[2]^=res[2];
}
lres[0]=lres[1]=lres[2]=0;
for(i=0;i<3;i++)
if(rres[i])
{
k=i;
break;
}
while(l<r)
{
mid=(l+r)>>1;
mres[0]=mres[1]=mres[2]=0;
for(i=1;i<=n;i++)
{
calc(c,x[i],y[i],mid);
mres[0]^=res[0];mres[1]^=res[1];mres[2]^=res[2];
}
if(mres[k]^lres[k])
r=mid,memcpy(rres,mres,sizeof(int)*3);
else
l=mid+1,memcpy(lres,mres,sizeof(int)*3);
}
return l;
}
inline bool light(ll x,ll y)
{
int res=0;
ll xx,yy,n,m;
register int i;
for(i=1;i<=::n;i++)
{
xx=::x[i];yy=::y[i];
n=xx-x;m=y-yy;
if(m<0||m>n)
continue;
res^=((n|m)==n);
}
return res;
}
inline void solve(ll c,pair<ll,ll> &a)
{
ll k=epc(c),lk=k,rk=k;
// fprintf(stderr,"%lld\n",k);
register ll i;
for(i=1ll<<62;i;i>>=1)
if(light(c,lk-i))
lk-=i;
for(i=1ll<<62;i;i>>=1)
if(light(c,rk+i))
rk+=i;
a.first=c+(rk-lk);a.second=lk;
return;
}
signed main()
{
pair<ll,ll> a;
register int i;
scanf("%d",&n);
for(i=1;i<=n;i++)
scanf("%lld%lld",&x[i],&y[i]);
solve(-100000000000000000,a);
printf("%lld %lld\n",a.first,a.second);
return 0;
}

AtCoder WTF 2019 C2. Triangular Lamps Hard的更多相关文章

  1. AtCoder ExaWizards 2019 简要题解

    AtCoder ExaWizards 2019 简要题解 Tags:题解 link:https://atcoder.jp/contests/exawizards2019 很水的一场ARC啊,随随便便就 ...

  2. AtCoder diverta 2019 Programming Contest 2

    AtCoder diverta 2019 Programming Contest 2 看起来我也不知道是一个啥比赛. 然后就写写题解QWQ. A - Ball Distribution 有\(n\)个 ...

  3. AtCoder ExaWizards 2019 D Modulo Operations

    题意 给出一个长度为\(n\)的数列和数字\(X\),对于数列的每一种排列,其权值\(X\)依次对排列中的数取模,求出\(n!\)种情况最后剩下的数的权值和 分析 如果大的数字排在小的数字后面,那么大 ...

  4. AtCoder M-SOLUTIONS 2019 Task E. Product of Arithmetic Progression

    problem link Official editorial: code: int main() { #if defined LOCAL && !defined DUIPAI ifs ...

  5. AtCoder Beginner Contest 133-C - Remainder Minimization 2019

    https://atcoder.jp/contests/abc133/tasks/abc133_c 思路:由于L,R区间太大,所以不能暴力枚举.由于求(i*j)%2019的最小值,那么2019的倍数对 ...

  6. [AtCoder] NIKKEI Programming Contest 2019 (暂缺F)

    [AtCoder] NIKKEI Programming Contest 2019   本来看见这一场的排名的画风比较正常就来补一下题,但是完全没有发现后两题的AC人数远少于我补的上一份AtCoder ...

  7. [AtCoder] Yahoo Programming Contest 2019

    [AtCoder] Yahoo Programming Contest 2019   很遗憾错过了一场 AtCoder .听说这场是涨分场呢,于是特意来补一下题. A - Anti-Adjacency ...

  8. 【AtCoder】Tenka1 Programmer Contest 2019

    Tenka1 Programmer Contest 2019 C - Stones 题面大意:有一个01序列,改变一个位置上的值花费1,问变成没有0在1右边的序列花费最少多少 直接枚举前i个都变成0即 ...

  9. 【AtCoder】ExaWizards 2019

    ExaWizards 2019 C - Snuke the Wizard 发现符文的相对位置不变,直接二分某个位置是否到达最左或最右来计算 #include <bits/stdc++.h> ...

随机推荐

  1. Java并发(二)异步转同步

    目录 前置条件:构造一个异步调用 一.使用wait和notify方法 二.使用条件锁 三.Future 四.使用CountDownLatch 五.使用CyclicBarrier 总结 在Java并发编 ...

  2. AI 最小二乘法

    最小二乘法 参考链接: https://zhuanlan.zhihu.com/p/27204466

  3. saltstack配置管理之states

    states是saltstack中的配置语言,我们安装一个包,管理一个配置文件,最后保证服务的正常运行,都需要我们编写一些states sls文件(描述状态的文件)去描述和实现我们的功能.sls文件都 ...

  4. java并发编程CountDownLatch

    /** * CountDownLatch用法 * CountDownLatch类位于java.util.concurrent包下,利用它可以实现类似计数器的功能.比如有一个任务A, * 它要等待其他4 ...

  5. 移动端高清适配方案(解决图片模糊问题、1px细线问题)

    本文介绍了移动端适配的3种方法,以及移动端图片模糊问题和1px细线问题的解决方法.当然了,在这之前先整理了与这些方法相关的知识:物理像素.设备独立像素.设备像素比和viewport. >> ...

  6. jQuery的Cookie使用

    为程序设置Cookie,可以在C#内进行,也可以在前端进行.如jQuery的Cookie也是一个很不错的插件. 在使用之前,可以先使用NuGet来安装cookie: 在MVC的视图中,引用jQuery ...

  7. Java 中 LinkedList 和 ArrayList 的区别

    引自:https://www.cnblogs.com/huzi007/p/5550440.html ArrayList和LinkedList的大致区别如下:1.ArrayList是实现了基于动态数组的 ...

  8. [Spark][Python]对HDFS 上的文件,采用绝对路径,来读取获得 RDD

    对HDFS 上的文件,采用绝对路径,来读取获得 RDD: In [102]: mydata=sc.textFile("file:/home/training/test.txt")1 ...

  9. BZOJ 3561 DZY Loves Math VI

    BZOJ 3561 DZY Loves Math VI 求\(\sum_{i=1}^{n}\sum_{j=1}^{m}\text{lcm}(i,j)^{\gcd(i,j)}\),钦定\(n\leq m ...

  10. Http指南(3)

    Web主机托管 主机托管服务 虚拟主机托管:许多Web托管者通过让一些顾客共享一台计算机来提供便宜的Web主机托管服务.这称为共享主机托管或虚拟主机托管 虚拟服务器请求缺乏主机信息: 不幸的是,HTT ...