Preface

ZJOI一轮被麻将劝退的老年选手看到这题就两眼放光,省选也有乱搞题

然后狂肝了3~4天终于打完了,期间还补了一堆姿势

由于我压缩技术比较菜,所以用的都是非打表算法,所以一共写了5K……

话不多说我们慢慢分析这道神题(真的是慢慢,最后还会放上许多辅助的CODE)


Case1~Case3

首先这几个点就是让你熟悉一下题目意思的

我们套路地发现这题由两部分组成,他们的功能编号开头分别为\(1/2\)

然后点开第一个点,发现第一个是数据组数?剩下的输入一个\(x\)然后就输出一个数

通过\(0\to1,1\to 19,2\to 361\)我们发现这个就是\(19^x\)

之后就能理解\(998244353\)是什么了,其实就是模数

那么很简单,Case1暴力推就可以了,Case2指数在long long内直接快速幂即可

Case3我们通过欧拉定理,\(x^p=x^{p\mod\phi(p)}\),当\(\text{p is a prime number}\)时,有\(x^p=x^{p\mod p-1}\)

一边读入一边取模即可


Case4

\(998244353\)变成了?,我们发现这时候模数要自己猜

打开答案文件发现数据普遍很小,所以我们找出最大的数\(1145098\),然后向后枚举判断即可

判断的时候只需要比对第一个的答案即可,这个可以很快找出最后的模数是\(1145141\)


Case5

哎呀怎么又没有模数了,打开答案文件一看那庞大的数据范围看来就不能暴力枚举模数了

那么我们考虑我们一般找模数的过程,像这种单调增函数取模的时候肯定存在一个\(x\),使得\(f(x-1)>f(x)\)(\(f(x)=19^x\mod p\))

那么我们考虑用这种方法求出模数,首先找出一对\(x,y(x<y)\)使得\(f(x)>f(y)\)且\(x,y\)尽量接近

写个代码跑一下会得到这样的一组数据:

264708066 1996649514996338529
264708068 1589589654696467295

然后我们计算差值,\(264708066\times19^2-1589589654696467295=719200885258981741674\)

显然此时模数必定是\(719200885258981741674\)的一个因数,我们考虑它还要大于最大数\(5211500658258874318\),所以在\([100,200]\)中枚举一个约数,求出另一个约数\(5211600617818708273\)即是最后的模数

下面放一下找差值的代码以及求约数的Python代码:

#include<cstdio>
#include<cctype>
#include<algorithm>
using namespace std;
const int N=10005;
struct data
{
int x; long long y;
friend inline bool operator < (const data& A,const data& B)
{
return A.x<B.x;
}
}a[N]; int n,mi=1e9,pos;
int main()
{
freopen("mindlt.txt","w",stdout);
FILE *fin1=fopen("software.in","r"),*fin2=fopen("software5.ans","r");
register int i; char str[20]; fscanf(fin1,"%s",str+1);
for (fscanf(fin1,"%d",&n),i=1;i<=n;++i) fscanf(fin1,"%d",&a[i].x);
for (i=1;i<=n;++i) fscanf(fin2,"%lld",&a[i].y);
for (sort(a+1,a+n+1),i=2;i<=n;++i) if (a[i].y<a[i-1].y)
{
if (a[i].x-a[i-1].x<mi) mi=a[i].x-a[i-1].x,pos=i;
}
return printf("%d %lld\n%d %lld",a[pos-1].x,a[pos-1].y,a[pos].x,a[pos].y),0;
}
for i in range(100,201):
if 719200885258981741674%i==0:
if 719200885258981741674//i>5211500658258874318:
print(719200885258981741674//i,end=' ')

最后提醒一点,两个模数范围的数相加都会爆long long,所以必须开unsigned long long

Case6~Case7

艾玛这个\(998244353\)前面加个wa是什么鬼

打开答案文件发现输出有了负数,相信这个大家平时都有经历过,显然是没开long long炸了

那么快速幂我怎么知道要在哪里取模呢?没事Case6单次暴力乘起来即可,但是这样过不了Case7啊

不要慌我们意识到这种构造数列的方法类似于生日悖论,是很容易成环的

那么我们直接开一个map找出环然后直接做即可

这里给出找环的CODE,输出的第一个数是环之前的位置,第二个数是环的长度

#include<cstdio>
#include<map>
#define RI register int
using namespace std;
const int N=10000005,mod=998244353;
int lst,nw; map <int,int> pos;
int main()
{
freopen("circle.txt","w",stdout);
pos[lst=1]=0; for (RI i=1;;++i)
{
nw=19*lst%mod; if (pos.count(nw))
return printf("%d %d",pos[nw]-1,i-pos[nw]),0;
pos[nw]=i; lst=nw;
}
return 0;
}

Case8~Case10

woc终于写完第一个部分了,然后发现这第二个点的输出怎么都那么大呢

点开一看woc一片乱七八糟的字符?大致发现了输入可能是一个区间?然后每个数输出了一个字符

仔细分析加上适当联想(\(\text{p=prime}\))我们发现这就是个素性检测

那么很简单,Case8一发线性筛,Case9可以筛出前\(10^6\)然后拿到这里筛,Case10。。。

可以选择打表,因为两个素数间的间隔很大,可以直接记录差值然后压缩起来

但是判素数我们还有一大法宝——Miller_Rabin,这里的MR不需卡常以及鬼畜选参数,直接做\(10\)次都能过

所以还算是轻松地结束了


Case11~Case13

这里根据上面的套路我们点开答案文件发现只有0,+,-三种字符

然后结合\(u\)的提示很容易想到这就是区间求\(\mu\),根据\(\mu\)的定义我们大力来一发质因数分解?

然后悲惨的我复习了Pollard-Rho之后发现这东西在运行多组数据时就是个弟弟,连Case11都跑不过233

那只能沿袭上面的套路了,Case11可以线性筛,Case12直接用\(10^6\)的素数来筛即可

那么Case13的做法就比较诡异了,这里讲一种LOJ上看到的做法:

首先类似于Case12,先筛出\(10^6\)内所有素数,然后先像上面一样筛一遍,同时记录每一个数此时的乘积

分解结束后看一下,如果还有剩下的因数,那么其实只要判断以下情况即可:

  • 剩下的因数为素数,直接MR判一发即可
  • 剩下一个平方数,直接sqrt后回代判断,并且直接把\(\mu\)置为\(0\)
  • 这个数是两个不同的大于\(10^6\)的素数的乘积(容易发现不可能是三个及以上的积),这个什么都不干即可(乘两个\(-1\)等于不变)

然后写一发你就会发现TLE飞了,看一下真正慢的其实是MR哪里

然后我们就要利用欧洲玄学了,经过试验我们发现MR的底数可以只用\(2,3\)(据说只用一个\(2\)都能过)来跑,然后速度上卡过去了,且没有打表需求!


Case14~Case16

这个根据上面的套路直接观察+大力猜测发现\(原根\text{g=原根}\)

然后根据基本数论技巧我们知道判断一个数是否是另一个数的原根只要判断对于\(p\)的所有质因数\(p'\)都有\(x^{\frac{\phi(p)}{p'}}\mod p\not= 1\)

然后发现\(\phi(998244353)=998244352\)只有\(3\)个质因数,所以暴力做就可以通过Case14

那么Case15是什么鬼,区间筛原根?其实还真的可以,我们利用原根于指标的关系可以发现先找出任意一个原根,然后求出关于它的指标就得到这个数是原根当且仅当该指标与\(\phi(p)\)互质

这个直接大力分解质因数枚举一发即可,即可通过Case15

然后就是最恶心的Case16了,感觉上可以用偏数学的方法求出,但是我们可以乱搞求出模数

意识到\([10^9,2\times10^9]\)内很多素数,出题人为了卡你肯定要把正确的那个放在中间一点

所以我们从中间向两侧枚举,用MR判素数,然后怎么检测这个数是否符合要求呢

很简单,我们把答案的前\(50\)个全部记下来,因为\(\phi(p) \mod 2=0\),所以必然有质因数\(2\)

我们只用这个来判断,一旦出现这个都不合法但答案却是合法的情况即说明这个数显然不行

那么耐性地等待一小会(20s不到)我们就可以得到模数\(1515343657\)了(正着找可能要几分钟吧)

这里给出暴力找的CODE

#include<cstdio>
#include<cctype>
#define RI register int
#define CI const int&
using namespace std;
const int MR_prime[3]={2,3,61},ST=233333333,MID=1500000000;
const bool tar[50]={0,0,0,1,1,1,0,0,1,1,0,1,0,0,0,1,0,0,1,1,0,0,1,0,1,1,0,0,0,0,0,0,1,1,0,0,1,0,0,0,0,0,0,1,1,0,0,1,1,0};
inline int quick_pow(int x,int p,int mod,int mul=1)
{
for (;p;p>>=1,x=1LL*x*x%mod) if (p&1) mul=1LL*mul*x%mod; return mul;
}
inline bool Singer_MR(CI x,CI p)
{
if (quick_pow(x,p-1,p)!=1) return 0;
int t=p-1; while (!(t&1))
{
t>>=1LL; int val=quick_pow(x,t,p);
if (val!=1&&val!=p-1) return 0;
if (val==p-1) return 1;
}
return 1;
}
inline bool Miller_Rabin(CI x)
{
RI i; for (i=0;i<3;++i) { if (x==MR_prime[i]) return 1; if (x%MR_prime[i]==0) return 0; }
for (i=0;i<3;++i) if (!Singer_MR(MR_prime[i],x)) return 0; return 1;
}
inline bool check(CI mod)
{
for (RI i=0;i<50;++i) if (quick_pow(ST+i,mod-1>>1,mod)==1&&tar[i]) return 0; return 1;
}
int main()
{
freopen("gr_mod.txt","w",stdout);
for (RI i=0;;++i)
{
if (Miller_Rabin(MID-i)&&check(MID-i)) { printf("%d %d",MID-i,i); break; }
if (Miller_Rabin(MID+i)&&check(MID+i)) { printf("%d %d",MID+i,i); break; }
}
return 0;
}

ALL CODE

#include<cstdio>
#include<cctype>
#include<cmath>
#include<cstring>
#define RI register int
#define RL register LL
#define CI const int&
#define CL const LL&
#define Tp template <typename T>
using namespace std;
typedef long long LL;
class FastInputOutput
{
public:
int pt[25];
Tp inline void read(T& x)
{
x=0; char ch; while (!isdigit(ch=getchar()));
while (x=(x<<3)+(x<<1)+(ch&15),isdigit(ch=getchar()));
}
Tp inline void read(T& x,const T& mod)
{
x=0; char ch; while (!isdigit(ch=getchar()));
while (x=(10ull*x+(ch&15))%mod,isdigit(ch=getchar()));
}
Tp inline void write(T x)
{
if (!x) return (void)(putchar('0'),putchar('\n'));
if (x<0) putchar('-'),x=-x;
RI ptop=0; while (x) pt[++ptop]=x%10,x/=10;
while (ptop) putchar(pt[ptop--]+48); putchar('\n');
}
}F;
namespace Case1 //19^x%mod
{
static const int L=101000,st=55244,len=45699;
int n,val[L+5]; LL x,mod;
inline void inc(LL& x,CL y)
{
unsigned long long t=x+y; x=t>=mod?t-mod:t;
}
inline LL quick_mul(LL x,LL y,LL sum=0)
{
for (;y;inc(x,x),y>>=1) if (y&1) inc(sum,x); return sum;
}
inline LL quick_pow(LL p,LL x=19,LL mul=1)
{
for (;p;p>>=1,x=quick_mul(x,x))
if (p&1) mul=quick_mul(mul,x); return mul;
}
inline void work(void)
{
for (F.read(n);n;--n) F.read(x,mod-1),F.write(quick_pow(x));
}
inline void wa_work(void)
{
val[0]=1; for (RI i=1;i<=L;++i) val[i]=19*val[i-1]%mod;
for (F.read(n);n;--n) F.read(x),F.write(val[x<=st?x:((x-st)%len+st)]);
}
/*inline int str_mod(const char *str,CI mod,int ret=0)
{
int len=strlen(str); for (RI i=0;i<len;++i)
ret=((ret<<3)+(ret<<1)+(str[i]&15))%mod; return ret;
}*/
inline void solve(void)
{
char opt=getchar(); if (opt=='_') return F.read(n),mod=998244353,work();
if (opt=='w') return F.read(n),mod=998244353,wa_work();
/*for (RI i=1145099;;++i) if (Miller_Rabin(i))
{
if (mod=i,quick_pow(str_mod("627811703016764290815178977207148434322",mod-1))==642666)
return;
}*/
opt=getchar(); if (opt=='+') mod=5211600617818708273LL; else mod=1145141; work();
}
};
namespace Case2 //number identify
{
const int MR_prime[3]={2,3},N=1e6,MX=13123111;
int n,prime[N+5],id[MX+5],mpr[N+5],mu[N+5],cnt,tot,mod;
LL l,r,mul[N+5],t; bool vis[MX+5];
inline LL quick_mul(CL x,CL y,CL mod)
{
LL k=(LL)((1.0L*x*y)/(1.0L*mod)),r=x*y-k*mod;
r-=mod; while(r<0LL) r+=mod; return r;
}
inline LL quick_pow(LL x,LL p,LL mod,LL mul=1)
{
for (;p;p>>=1,x=quick_mul(x,x,mod))
if (p&1) mul=quick_mul(mul,x,mod); return mul;
}
inline bool Singer_MR(CI x,CL p)
{
if (quick_pow(x,p-1,p)!=1) return 0;
LL t=p-1; while (!(t&1))
{
t>>=1LL; LL val=quick_pow(x,t,p);
if (val!=1&&val!=p-1) return 0;
if (val==p-1) return 1;
}
return 1;
}
inline bool Miller_Rabin(CL x)
{
RI i; for (i=0;i<2;++i) { if (x==MR_prime[i]) return 1; if (x%MR_prime[i]==0) return 0; }
for (i=0;i<2;++i) if (!Singer_MR(MR_prime[i],x)) return 0; return 1;
}
inline void prime_solve(void)
{
for (F.read(n);n;--n)
{
F.read(l); F.read(r); for (RL i=l;i<=r;++i)
putchar(Miller_Rabin(i)?'p':'.'); putchar('\n');
}
}
#define Pi prime[j]
inline void init(CI n)
{
vis[1]=mu[1]=1; for (RI i=2;i<=n;++i)
{
if (!vis[i]) prime[++cnt]=i,mu[i]=-1;
for (RI j=1;j<=cnt&&i*Pi<=n;++j)
{
vis[i*Pi]=1; if (i%Pi) mu[i*Pi]=-mu[i]; else break;
}
}
}
inline void mu_solve(void)
{
for (init(N),F.read(n);n;--n)
{
RI i,j; F.read(l); F.read(r); int len=r-l+1; if (r<=N)
{
for (i=l;i<=r;++i) putchar(mu[i]?(~mu[i]?'+':'-'):'0');
putchar('\n'); continue;
}
for (i=1;i<=len;++i) mu[i]=mul[i]=1; for (j=1;j<=cnt;++j)
for (RL i=1LL*((l-1)/Pi+1)*Pi;i<=r;i+=Pi)
if (i%(1LL*Pi*Pi)==0) mu[i-l+1]=0; else mu[i-l+1]*=-1,mul[i-l+1]*=Pi;
for (i=1;i<=len;++i)
{
if (!mu[i]) { putchar('0'); continue; }
if (mul[i]!=i+l-1)
{
if (Miller_Rabin(t=(i+l-1)/mul[i])) mu[i]*=-1; else
{
LL sq=(LL)sqrt(t); if (sq*sq==t) mu[i]=0;
}
}
if (!mu[i]) putchar('0'); else putchar(~mu[i]?'+':'-');
} putchar('\n');
}
}
inline void resolve(int x)
{
tot=0; for (RI j=1;Pi*Pi<=x;++j) if (x%Pi==0)
{
mpr[++tot]=Pi; while (x%Pi==0) x/=Pi;
}
if (x>1) mpr[++tot]=x;
}
#undef Pi
inline bool is_GR(CI x)
{
for (RI i=1;i<=tot;++i)
if (quick_pow(x,(mod-1)/mpr[i],mod)==1) return 0; return 1;
}
inline void GR_Sieve(CI mod)
{
RI i,j; memset(vis,0,sizeof(vis)); int gr,pfx;
for (i=1;i<mod;++i) if (is_GR(i)) { gr=i; break; }
for (i=1,pfx=gr;i<mod;++i,pfx=1LL*pfx*gr%mod) id[pfx]=i;
for (i=1;i<=tot;++i) for (j=mpr[i];j<mod;j+=mpr[i]) vis[j]=1;
for (i=1;i<mod;++i) putchar(vis[id[i]]?'.':'g');
}
inline void GR_solve(void)
{
for (init(1e5),F.read(n);n;--n)
{
F.read(l); F.read(r); if (r==234133333) mod=1515343657; else F.read(mod);
if (mod==998244353||mod==1515343657)
{
resolve(mod-1); for (RI i=l;i<=r;++i)
putchar(is_GR(i)?'g':'.');
} else resolve(mod-1),GR_Sieve(mod); putchar('\n');
}
}
inline void solve(void)
{
char opt=getchar(); switch (opt)
{
case 'p':
prime_solve(); break;
case 'u':
mu_solve(); break;
case 'g':
GR_solve(); break;
}
}
};
int main()
{
//freopen("software.in","r",stdin); freopen("software.out","w",stdout);
char opt=getchar(); if (opt=='1') Case1::solve(); else Case2::solve();
return 0;
}

Postscript

至此这道毒瘤题终于宣告终结,不得不说它改变了传统题的出题方式

放在赛场上这题就是防AK的绝佳手段,平时肝一肝可以,但是比赛的时候最好还是按照性价比拿分,合理安排吧

最后小声BB一句如果ZJOI也有这种乱搞题那不是很有趣(希望吉利二试能了一个心愿)233

Luogu P5285 [十二省联考2019]骗分过样例的更多相关文章

  1. Luogu P5285 / LOJ3050 【[十二省联考2019]骗分过样例】

    伪提答害死人...(出题人赶快出来挨打!!!) 虽说是考场上全看出来是让干嘛了,然而由于太菜以及不会打表所以GG了,只拿了\(39\)... 经测试,截至\(2019.4.18-11:33\),这份接 ...

  2. Luogu5285 [十二省联考2019] 骗分过样例

    题目分析: 观察前3个点,$361=19*19$,所以可以发现实际上就是快速幂,然后模数猜测是$998244353$,因为功能编号里面有这个数字,用费马小定理处理一下. $pts:12$ 观察第4个点 ...

  3. [十二省联考2019]骗分过样例 luoguP5285 loj#3050

    不解释(因为蒟蒻太弱了,肝了一晚受不了了...现在省选退役,这有可能就是我做的最后一题了... #include<bits/stdc++.h> using namespace std; # ...

  4. luogu P5291 [十二省联考2019]希望

    luogu loj 无论最终结果将人类历史导向何处 \(\quad\)我们选择 \(\quad\quad\)\(\large{希望}\) 诶我跟你讲,这题超修咸的 下面称离连通块内每个点距离不超过\( ...

  5. Luogu P5290 [十二省联考2019]春节十二响

    这题是最近看到的今年省选题中最良心的一道了吧 看题+想题+写题都可以在0.5h内解决,送分含义明显啊 首先理解了题意后我们很快就能发现两个点如果要被分在一段那么必须在它们的祖先处合并 首先我们考虑下二 ...

  6. Luogu P5284 [十二省联考2019]字符串问题

    好难写的字符串+数据结构问题,写+调了一下午的说 首先理解题意后我们对问题进行转化,对于每个字符串我们用一个点来代表它们,其中\(A\)类串的点权为它们的长度,\(B\)类串的权值为\(0\) 这样我 ...

  7. Luogu P5283 [十二省联考2019]异或粽子

    感觉不是很难的一题,想了0.5h左右(思路歪了,不过想了一个大常数的两只\(\log\)做法233) 然后码+调了1h,除了一个SB的数组开小外基本上也没什么坑点 先讲一个先想到的方法,我们对于这种问 ...

  8. luogu P5289 [十二省联考2019]皮配

    传送门 首先考虑一个正常的dp,设\(f_{i,j,k}\)为前\(i\)个学校,\(j\)人在\(\color{#0000FF}{蓝阵营}\),\(k\)人在\(\color{#654321}{吔} ...

  9. 【题解】Luogu P5284 [十二省联考2019]字符串问题

    原题传送门 我用sa做的本题 (码量似乎有点大) 先对原串建sa 考虑如何建图: 从大到小枚举长度len 先将height中等于len的两个位置在并查集合并起来,将lst也合并(lst是链表) 再将长 ...

随机推荐

  1. Thymeleaf 3.0 专题

    http://www.thymeleaf.org/doc/articles/layouts.html thymeleaf的初次使用(带参请求以及调用带参js方法) 之前对于前端框架接触较少,第一次接触 ...

  2. When to use next() and return next() in Node.js

    Some people always write return next() is to ensure that the execution stops after triggering the ca ...

  3. salesforce lightning零基础学习(四) 事件(component events)简单介绍

    lightning component基于事件驱动模型来处理用户界面的交互.这种事件驱动模型和js的事件驱动模型也很相似,可以简单的理解成四部分: 1.事件源:产生事件的地方,可以是页面中的输入框,按 ...

  4. VM虚拟机安装centos详细图文教程

    本教程贴,采用VM虚拟机进行安装, Ps:不懂VM使用的,可以百度一下 第一步,启动虚拟机,并进行新建---虚拟机·· 选择 从镜像安装,吧里有6.3镜像下载的链接的 然后, 下一步 . 选择客户机版 ...

  5. CSS布局-圣杯布局

    圣杯布局 圣杯布局很完美(兼容所有浏览器,包括IE6),但是使用了相对定位,布局有局限性,宽度控制要改的地方也多. 第一种方法公用部分: .lgyz, .lzrg, .lrzcg, .lcgrz, . ...

  6. Canvas的基本用法

    canvas没有设置宽度和高度的时候,会初始化宽度:300像素和高度:150像素.可以使用CSS来定义大小,但在绘制时图像会伸缩以适应它的框架尺寸:如果CSS的尺寸与初始画布的比例不一致,它会出现扭曲 ...

  7. segmenter.go

    ; ;; ].minDistance ; ].text),, ;; ;; ;,) {             output = append(output, toLower(text[alphanum ...

  8. key.go

    package].Key)         if err = waitDelete(ctx, client, lastKey, resp.Header.Revision); err != nil { ...

  9. 「LOJ 2289」「THUWC 2017」在美妙的数学王国中畅游——LCT&泰勒展开

    题目大意: 传送门 给一个动态树,每个节点上维护一个函数为$f(x)=sin(ax+b)$.$f(x)=e^{ax+b}$.$f(x)=ax+b$中的一个. 支持删边连边,修改节点上函数的操作. 每次 ...

  10. BZOJ_4765_普通计算姬_分块+dfs序+树状数组

    BZOJ_4765_普通计算姬_分块 Description "奋战三星期,造台计算机".小G响应号召,花了三小时造了台普通计算姬.普通计算姬比普通计算机要厉害一些 .普通计算机能 ...