NOIp2018集训test-9-8(pm) (联考一day2)
把T1题读错了,想了一个多小时发现不可做。然后打了t2,常数不优秀。然后去打t3,lct,结果打挂爆0了。
然后今天就爆炸了。
如果这是noip我今年就可以直接回去学常规了。学常规多好,多开心。
今天考完llj同学又来机房“羞辱(杯哥曰)”我这个zz,用大概5min就AK了这套题,我真是菜哭自己了。。
T1锻造
这tm不是个傻逼题吗。我tm没有看到y=max(0,x-1),然后我以为要枚举y然后取min。然后我推了一推,发现是个凸壳的形式倒是可以O(n)做,问题是取摸怎么tm取min啊??我就很懵逼地又推了半天没有任何进展。
结果每个x由x-1,x-2锻造来,随便写写方程,1的时候特殊处理就好了。
1 //Achen
2 #include<algorithm>
3 #include<iostream>
4 #include<cstring>
5 #include<cstdlib>
6 #include<vector>
7 #include<cstdio>
8 #include<queue>
9 #include<cmath>
10 #include<set>
11 #include<map>
12 #define Formylove return 0
13 #define For(i,a,b) for(int i=(a);i<=(b);i++)
14 #define Rep(i,a,b) for(int i=(a);i>=(b);i--)
15 const int N=1e7+7,p=998244353;
16 typedef long long LL;
17 typedef double db;
18 using namespace std;
19 int n,b[N],c[N],f[N],inv[N];
20 LL a,bx,by,cx,cy,pp;
21
22 template<typename T>void read(T &x) {
23 char ch=getchar(); x=0; T f=1;
24 while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
25 if(ch=='-') f=-1,ch=getchar();
26 for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
27 }
28
29 #define ANS
30 int main() {
31 #ifdef ANS
32 freopen("forging.in","r",stdin);
33 freopen("forging.out","w",stdout);
34 #endif
35 read(n); read(a);
36 read(bx); read(by); read(cx); read(cy); read(pp);
37 b[0]=by+1;c[0]=cy+1;
38 for(int i=1;i<n;i++){
39 b[i]=((LL)b[i-1]*bx+by)%pp+1;
40 c[i]=((LL)c[i-1]*cx+cy)%pp+1;
41 }
42 inv[0]=inv[1]=1;
43 For(i,2,pp) inv[i]=(p-(LL)p/i*inv[p%i]%p)%p;
44 f[0]=a;
45 f[1]=((LL)c[0]*inv[min(b[0],c[0])]%p+1)*a%p;
46 For(i,2,n)
47 f[i]=((LL)f[i-2]+(LL)f[i-1]*c[i-1]%p*inv[min(c[i-1],b[i-2])]%p)%p;
48 printf("%d\n",f[n]);
49 Formylove;
50 }
------------------18-9-11upd--------------------
其实是T2的upd,写错位置懒得改了
积性筛是什么辣鸡算法??我的辣鸡电脑跑std2s才出答案,看llj200倍吊打标解
求x^(m-1)=1(mod p)的x的个数,x=g^a(g为原根),原式化成g^(a*(m-1))=1(mod p),因为g^(p-1)=1(mod p),a*(m-1)=k*(p-1),一个gcd解决问题。
只需把积性筛换成一行solve
LL solve(int P,int m) { return gcd(m-1,P-1); }
ORZ ORZ ORZ
我跟llj之间大概隔着几个世纪的代沟
1 //Achen 2 #include<algorithm> 3 #include<iostream> 4 #include<cstring> 5 #include<cstdlib> 6 #include<vector> 7 #include<cstdio> 8 #include<queue> 9 #include<cmath> 10 #include<set> 11 #include<map> 12 #define Formylove return 0 13 #define For(i,a,b) for(register int i=(a);i<=(b);i++) 14 #define Rep(i,a,b) for(int i=(a);i>=(b);i--) 15 const int N=1e4+7,mod=998244353; 16 typedef long long LL; 17 typedef double db; 18 using namespace std; 19 int id,T; 20 LL c,m; 21 22 template<typename T>void read(T &x) { 23 char ch=getchar(); x=0; T f=1; 24 while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar(); 25 if(ch=='-') f=-1,ch=getchar(); 26 for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f; 27 } 28 29 LL ksm(LL a,LL b,LL p) { 30 LL rs=1,bs=a%p; 31 while(b) { 32 if(b&1) rs=rs*bs%p; 33 bs=bs*bs%p; 34 b>>=1; 35 } 36 return rs; 37 } 38 39 int gcd(int a,int b) { return !b?a:gcd(b,a%b); } 40 41 LL solve(int P,int m) { return gcd(m-1,P-1); } 42 43 #define ANS 44 int main() { 45 #ifdef ANS 46 freopen("division.in","r",stdin); 47 freopen("division.out","w",stdout); 48 #endif 49 read(id); 50 read(T); 51 while(T--) { 52 read(c); read(m); 53 int pp; 54 if(m==1) { 55 LL ans=1; 56 For(i,1,c) { 57 read(pp); 58 ans=ans*pp%mod; 59 } 60 printf("%lld\n",ans); 61 } 62 else if(m==2) { 63 For(i,1,c) read(pp); 64 printf("%lld\n",ksm(2,c,mod)); 65 } 66 else { 67 LL ans=1,tot=0; 68 For(i,1,c) { 69 read(pp); 70 tot=solve(pp,m); 71 ans=ans*(tot+1)%mod; 72 } 73 printf("%lld\n",ans); 74 } 75 } 76 Formylove; 77 }
T2整除
式子拆开就是x^(m-1)=1(mod pi) 或x==0 (mod pi)
枚举1~pi中满足条件的数,其他满足条件数就是在mod pi意义下于这些数同余。
那么可以得到c个x mod pi = bi同余方程,x在mod p1*p2*p3……pc意义下有唯一解。于是答案就是同余方程组的个数。也就是每个pi找到的1~pi中满足条件的数的个数+1的乘积。
这样就可以得到80分啦。
然后a^k还用暴力算吗??这是积性函数啊,线筛就好了我是个zz吧。
1 //Achen
2 #include<algorithm>
3 #include<iostream>
4 #include<cstring>
5 #include<cstdlib>
6 #include<vector>
7 #include<cstdio>
8 #include<queue>
9 #include<cmath>
10 #include<set>
11 #include<map>
12 #define Formylove return 0
13 #define For(i,a,b) for(register int i=(a);i<=(b);i++)
14 #define Rep(i,a,b) for(int i=(a);i>=(b);i--)
15 const int N=1e4+7,mod=998244353;
16 typedef long long LL;
17 typedef double db;
18 using namespace std;
19 int id,T;
20 LL c,m;
21
22 template<typename T>void read(T &x) {
23 char ch=getchar(); x=0; T f=1;
24 while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
25 if(ch=='-') f=-1,ch=getchar();
26 for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
27 }
28
29 LL ksm(LL a,LL b,LL p) {
30 LL rs=1,bs=a%p;
31 while(b) {
32 if(b&1) rs=rs*bs%p;
33 bs=bs*bs%p;
34 b>>=1;
35 }
36 return rs;
37 }
38
39 int bo[N],p[N],f[N];
40 LL solve(int P,int m) {
41 memset(bo,0,sizeof(bo)); p[0]=0;
42 f[1]=1;
43 int rs=1;
44 For(i,2,P) {
45 if(!bo[i]) {
46 p[++p[0]]=i;
47 f[i]=ksm(i,m-1,P);
48 }
49 for(int j=1;j<=p[0]&&i*p[j]<=P;j++) {
50 bo[i*p[j]]=1;
51 f[i*p[j]]=(LL)f[i]*f[p[j]]%P;
52 if(i%p[j]==0) break;
53 }
54 if(f[i]==1) rs++;
55 }
56 return rs;
57 }
58
59 #define ANS
60 int main() {
61 #ifdef ANS
62 freopen("division.in","r",stdin);
63 freopen("division.out","w",stdout);
64 #endif
65 read(id);
66 read(T);
67 while(T--) {
68 read(c); read(m);
69 int pp;
70 if(m==1) {
71 LL ans=1;
72 For(i,1,c) {
73 read(pp);
74 ans=ans*pp%mod;
75 }
76 printf("%lld\n",ans);
77 }
78 else if(m==2) {
79 For(i,1,c) read(pp);
80 printf("%lld\n",ksm(2,c,mod));
81 }
82 else {
83 LL ans=1,tot=0;
84 For(i,1,c) {
85 read(pp);
86 tot=solve(pp,m);
87 ans=ans*(tot+1)%mod;
88 }
89 printf("%lld\n",ans);
90 }
91 }
92 Formylove;
93 }
T3欠钱
法1:lct
其实我并不知道怎么做
法2:llj一眼就看出来的,然而我又不会。
法3
:
菜如我只会最傻逼的做法。启发式合并我用并查集记集合的大小,然后de了一下午,1是一次倍增的时候y写成了x,2是查询的时候没有考虑两个块不连通的情况,3是因为倍增数组一直在变,可能以前能到更深的地方现在到不了了,但是那里的数字还记着,查询到了就GG了,所以每次查询的时候要根据当前深度判断一下这个地方是不是现在可以到的。
1 //Achen
2 #include<algorithm>
3 #include<iostream>
4 #include<cstring>
5 #include<cstdlib>
6 #include<vector>
7 #include<cstdio>
8 #include<queue>
9 #include<cmath>
10 #include<set>
11 #include<map>
12 #define inf 1e9
13 #define Formylove return 0
14 #define For(i,a,b) for(int i=(a);i<=(b);i++)
15 #define Rep(i,a,b) for(int i=(a);i>=(b);i--)
16 const int N=2e5+7;
17 typedef long long LL;
18 typedef double db;
19 using namespace std;
20 int n,m,ans;
21
22 template<typename T>void read(T &x) {
23 char ch=getchar(); x=0; T f=1;
24 while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
25 if(ch=='-') f=-1,ch=getchar();
26 for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
27 }
28
29 int ecnt,fir[N],nxt[N<<1],to[N<<1],val1[N<<1],val2[N<<1];
30 void add(int u,int v,int w) {
31 nxt[++ecnt]=fir[u]; fir[u]=ecnt; to[ecnt]=v; val1[ecnt]=w; val2[ecnt]=1;
32 nxt[++ecnt]=fir[v]; fir[v]=ecnt; to[ecnt]=u; val1[ecnt]=w; val2[ecnt]=-1;
33 }
34
35 int fa[N],sz[N];
36 int find(int x) { return x==fa[x]?x:fa[x]=find(fa[x]); }
37
38 int R[N],f[N][17],g[N][17],h[N][17];
39 void dfs(int x,int fa) {
40 For(i,1,16) {
41 f[x][i]=f[f[x][i-1]][i-1];
42 if(!f[x][i]) break;
43 g[x][i]=min(g[x][i-1],g[f[x][i-1]][i-1]);
44 h[x][i]=h[x][i-1]+h[f[x][i-1]][i-1];
45 }
46 for(int i=fir[x];i;i=nxt[i]) if(to[i]!=fa) {
47 R[to[i]]=R[x]+1;
48 f[to[i]][0]=x;
49 g[to[i]][0]=val1[i];
50 h[to[i]][0]=val2[i];
51 dfs(to[i],x);
52 }
53 }
54
55 void merge(int x,int y,int z) {
56 add(x,y,z);
57 int gg=z,hh=1;
58 int rtx=find(x),rty=find(y);
59 if(sz[rtx]<sz[rty]) swap(x,y),swap(rtx,rty),hh=-1;
60 R[y]=R[x]+1; f[y][0]=x; g[y][0]=gg; h[y][0]=hh;
61 dfs(y,x);
62 sz[rtx]+=sz[rty];
63 fa[rty]=rtx;
64 }
65
66 int lca(int x,int y) {
67 if(R[x]<R[y]) swap(x,y);
68 Rep(i,16,0) if(R[x]>=(1<<i)+1&&R[f[x][i]]>=R[y])
69 x=f[x][i];
70 if(x==y) return x;
71 Rep(i,16,0) if(R[x]>=(1<<i)+1&&f[x][i]!=f[y][i])
72 x=f[x][i],y=f[y][i];
73 return f[x][0];
74 }
75
76 int qry(int x,int y) {
77 if(find(x)!=find(y)) return 0;
78 int z=lca(x,y),sum=0;
79 int ans=inf,L=R[x]+R[y]-2*R[z];
80 Rep(i,16,0) if(R[x]>=(1<<i)+1&&R[f[x][i]]>=R[z]) {
81 ans=min(ans,g[x][i]);
82 sum+=h[x][i];
83 x=f[x][i];
84 }
85 Rep(i,16,0) if(R[y]>=(1<<i)+1&&R[f[y][i]]>=R[z]) {
86 ans=min(ans,g[y][i]);
87 sum-=h[y][i];
88 y=f[y][i];
89 }
90 if(sum!=L) ans=0;
91 return ans;
92 }
93
94 #define ANS
95 int main() {
96 #ifdef ANS
97 freopen("money.in","r",stdin);
98 freopen("money.out","w",stdout);
99 #endif
100 read(n); read(m);
101 For(i,1,n) fa[i]=i,sz[i]=1,R[i]=1;
102 For(i,1,m) {
103 int o,a,b,c;
104 read(o);
105 if(!o) {
106 read(a); read(b); read(c);
107 a=(a+ans)%n+1;
108 b=(b+ans)%n+1;
109 c=(c+ans)%n+1;
110 merge(b,a,c);
111 }
112 else {
113 read(a); read(b);
114 a=(a+ans)%n+1;
115 b=(b+ans)%n+1;
116 ans=qry(a,b);
117 if(ans==759) {
118 int debug=1;
119 }
120 printf("%d\n",ans);
121 }
122 }
123 Formylove;
124 }
125 /*
126 5 10
127 0 4 3 1
128 0 3 2 3
129 0 2 1 6
130 0 5 2 1
131 1 4 1
132 */