T1 方程的解
一开始完全没思路,只好打特判(考完试发现特判一个都没用上),最后错的不能再错的错解给我搞到了60。
玄学。
这道题考试的时候思路很简单,就是枚举每一个x可能取到的值,用c与它做差,然后判断最后的结果y是否符合条件,O(n),就玩事儿了。
1 for (int i=1; i<=c/a; ++i) 2 { 3 c-=i*a; 4 if (!(c%b) and (c/b)>0) ans++; 5 c+=i*a; 6 if (ans>65535) {puts("ZenMeZheMeDuo"); flag=1; break;} 7 }
性价比挺高,但是我们还是要追求AC。
对于a b c有0的情况还是要特判掉的,因为exGCD不能处理0,无意义。
把0判掉后,c与他们的GCD一定整除,否则无解。
判掉这个后,再判a,b异号的情况,他们异号,直接无穷大,这个可以移项证明。
一定注意这两步操作的先后顺序,这个问题我也调了很长时间。
然后的操作就没有什么特别的了。
小弟不才。
1 #include<cstdio> 2 #include<iostream> 3 #define int long long 4 #define HZOI using namespace std 5 HZOI; 6 int T,a,b,c; 7 int ExGCD(int ,int ,int &,int &); 8 signed main() 9 { 10 scanf("%lld",&T); 11 while (T--) 12 { 13 scanf("%lld%lld%lld",&a,&b,&c); 14 if (!a and !b and !c) {puts("ZenMeZheMeDuo"); continue;} 15 if ((!a and b and !c) or (a and !b and !c) or (!a and !b and c)) {puts("0"); continue;} 16 if (!a and b and c) {if (c%b==0 and c*b>0) puts("ZenMeZheMeDuo"); else puts("0"); continue;} 17 if (a and !b and c) {if (c%a==0 and c*a>0) puts("ZenMeZheMeDuo"); else puts("0"); continue;} 18 int x,y; 19 int gcd=ExGCD(a,b,x,y); 20 if (c%gcd) {puts("0"); continue;} 21 if (a*b<0) {puts("ZenMeZheMeDuo"); continue;} 22 long long wc=c,miny=0,minx=0,maxy,maxx; 23 do {wc-=b,++miny;} while (wc%a); 24 maxx=wc/a; 25 wc=c; 26 do {wc-=a,++minx;} while (wc%b); 27 maxy=wc/b; 28 long long ans=(maxx-minx)/(b/gcd)+1; 29 if (ans>65535) {puts("ZenMeZheMeDuo");continue;} 30 printf("%lld ",ans>0?ans:0); 31 } 32 } 33 int ExGCD(int a,int b,int &x,int &y) 34 { 35 if (!b) { x=1; y=0; return a; } 36 int d=ExGCD(b,a%b,x,y); 37 int z=x; x=y; y=z-y*a/b; 38 return d; 39 }
T2 visit
考试的时候真的没有想到。
观察横纵走的净步数,设横走a反向b,纵走c反向d,我们发现,a-b==n,c-d==m,a+b+c+d=T,到这我们发现了一个特别重要的性质:他们的净步数不变,所以我们知道其中一个元素,就可以知道所有元素的值。
利用这一点,拿到30分就很简单了,对于30%数据,p为素数,所以我们可以直接Lucas,利用性质,求一个简单的组合数,30分。
由于题目中模数的特殊性,我们可以考虑用CRT(中国剩余定理),我们将模数分解质因数,将它分解成一个个小的素数,我们就可以对每一个素数快乐的进行Lucas,最后利用中国剩余定理合并答案。
快乐。
小弟不才。
1 #include<cstdio> 2 #include<cmath> 3 #define LL long long 4 #define HZOI using namespace std 5 HZOI; 6 int T,p,n,m,tot,prime[10]; 7 LL F[10][110003],Finv[10][110003],inv[10][110003],wc[10]; 8 inline void Init(int ); 9 inline LL Comb(int ,int ,int ); 10 inline void Fenjie(); 11 inline LL China(int ,int ); 12 inline LL Qpow(LL ,int ,int ); 13 LL Lucas(int ,int ,int ); 14 signed main() 15 { 16 scanf("%d%d%d%d",&T,&p,&n,&m); 17 Fenjie(); 18 for (register int i=1; i<=tot; ++i) 19 { 20 int mm=p/prime[i]; 21 wc[i]=mm*Qpow(mm,prime[i]-2,prime[i])%p; 22 } 23 for (register int i=1; i<=tot; ++i) Init(i); 24 if (n<0) n=-n; if (m<0) m=-m; 25 if (n<m) n^=m^=n^=m; 26 register LL ans=0,ojbk=T+n-m>>1; 27 for (register int a=n; a<=ojbk; ++a) 28 { 29 int b=a-n, c=(T+m+n>>1)-a, d=(T-m+n>>1)-a; 30 ans=(ans+China(T,a+b)*China(a+b,a)%p*China(c+d,c)%p)%p; 31 } 32 printf("%lld ",ans); 33 return 0; 34 } 35 inline LL China(int a,int b) 36 { 37 LL res=0; 38 for (register int i=1; i<=tot; ++i) 39 { 40 int mm=p/prime[i]; 41 res=(res+(wc[i]*(Lucas(a,b,i))%p)); 42 } 43 return res; 44 } 45 inline void Fenjie() // %remarkable 46 { 47 int lh=p,NB=sqrt(p); 48 for (register int i=2; i<=NB and lh^1; ++i) 49 if (!(lh%i)) prime[++tot]=i,lh/=i; 50 if (lh^1) prime[++tot]=lh; 51 } 52 LL Lucas(int a,int b,int k) 53 { 54 if (!b) return 1; 55 int q=prime[k]; 56 return Comb(a%q,b%q,k)*Lucas(a/q,b/q,k)%q; 57 } 58 inline LL Comb(int x,int y,int k) 59 { 60 if (x<y) return 0; 61 return F[k][x]%prime[k]*Finv[k][x-y]%prime[k]*Finv[k][y]%prime[k]; 62 } 63 inline void Init(int k) 64 { 65 int mod=prime[k]; 66 inv[k][0]=inv[k][1]=1; 67 for (register int i=2; i<=T; ++i) 68 inv[k][i]=Qpow(i,mod-2,mod); 69 F[k][0]=Finv[k][0]=1; 70 for (register int i=1; i<=T; ++i) 71 { 72 F[k][i]=F[k][i-1]*1ll*i%mod; 73 Finv[k][i]=Finv[k][i-1]*1ll*inv[k][i]%mod; 74 } 75 } 76 inline LL Qpow(LL a,int b,int mod) 77 { 78 LL res=1; 79 while (b) 80 { 81 if (b&1) res=res*a%mod; 82 a=a*a%mod; 83 b>>=1; 84 } 85 return res; 86 }
T3 光
沙雕题。
这道题没啥知识含量,纯模拟一格一格走60分。
三道题就这一道题有思路,无非是纯模拟就手玩,分了四种情况,每一种情况对应不同的转向与位置,唯一注意的就是在手玩的时候的方向位置的正确性,然后就没有什么了。
Dfs正向一遍反向一遍,因为光要结束只有两种情况:碰到死角,回到原点。它只要碰到死角就一定不会回到原点,反之亦然。
1 #include<cstdio> 2 #include<iostream> 3 #define HZOI using namespace std 4 HZOI; 5 int n,m,k,ans; 6 int vis[10003][10003]; 7 char fro1[2],fro2[2]; 8 inline int read(); 9 void Dfs(int ,int ,char []); 10 int main() 11 { 12 n=read(); m=read(); k=read(); 13 for (int i=1,x,y; i<=k; ++i) 14 { 15 x=read(); y=read(); 16 vis[x][y]=-1; 17 } 18 for (int i=0; i<=n+1; ++i) 19 vis[i][0]=vis[i][m+1]=-1; 20 for (int i=0; i<=m+1; ++i) 21 vis[0][i]=vis[n+1][i]=-1; 22 int x,y; 23 scanf("%d%d",&x,&y); 24 scanf("%s",fro1); 25 if (fro1[0]=='S') fro2[0]='N'; 26 else fro2[0]='S'; 27 if (fro1[1]=='E') fro2[1]='W'; 28 else fro2[1]='E'; 29 Dfs(x,y,fro1); 30 vis[x][y]=0; 31 Dfs(x,y,fro2); 32 printf("%d ",ans-1); 33 } 34 void Dfs(int x,int y,char from[2]) 35 { 36 // cout<<"x="<<x<<" y="<<y<<" 方向"<<from[0]<<from[1]<<endl; 37 if (vis[x][y]==1) {return ;} 38 ++ans; 39 vis[x][y]=1; 40 if (from[0]=='S') 41 { 42 if (from[1]=='E') 43 { 44 if (vis[x+1][y+1]!=-1) {Dfs(x+1,y+1,from); return ;} 45 if ((vis[x+1][y]==-1 and vis[x][y+1]!=-1)) {from[0]='N'; Dfs(x,y+1,from); return ;} 46 if (vis[x+1][y]!=-1 and vis[x][y+1]==-1) {from[1]='W'; Dfs(x+1,y,from); return ;} 47 return ; 48 } 49 else 50 { 51 if (vis[x+1][y-1]!=-1) {Dfs(x+1,y-1,from); return ;} 52 if (vis[x+1][y]==-1 and vis[x][y-1]!=-1) {from[0]='N'; Dfs(x,y-1,from); return ;} 53 if (vis[x+1][y]!=-1 and vis[x][y-1]==-1) {from[1]='E'; Dfs(x+1,y,from); return ;} 54 return ; 55 } 56 } 57 else 58 { 59 if (from[1]=='E') 60 { 61 if (vis[x-1][y+1]!=-1) {Dfs(x-1,y+1,from); return ;} 62 if (vis[x-1][y]==-1 and vis[x][y+1]!=-1) {from[0]='S'; Dfs(x,y+1,from); return ;} 63 if (vis[x-1][y]!=-1 and vis[x][y+1]==-1) {from[1]='W'; Dfs(x-1,y,from); return ;} 64 return ; 65 } 66 else 67 { 68 if (vis[x-1][y-1]!=-1) {Dfs(x-1,y-1,from); return ;} 69 if (vis[x-1][y]==-1 and vis[x][y-1]!=-1) {from[0]='S'; Dfs(x,y-1,from); return ;} 70 if (vis[x-1][y]!=-1 and vis[x][y-1]==-1) {from[1]='E'; Dfs(x-1,y,from); return ;} 71 return ; 72 } 73 } 74 } 75 inline int read() 76 { 77 int num=0; char ch=getchar(); 78 while (ch<'0' || ch>'9') ch=getchar(); 79 while (ch>='0' and ch<='9') num=(num<<3)+(num<<1)+(ch^48),ch=getchar(); 80 return num; 81 }
正解需要大量的STL,map用于判断是否是黑点,set/vector用于排序,目的是直接走到转向点。
这里我们要注意,它会得到转向点的坐标,而中间的坐标是忽略的,这也是为什么我们无法直接从起点开始一直转圈的原因(因为找不到出发点,不知到已经转回了出发点),所以我们先让光沿入射出发到第一个转向位置,再反向跑Dfs,两遍,问题就解决了。
不过还有一个问题是Dfs会爆栈,最后改成了while(1),但是有些人的Dfs就完美AC,不明所以。
小弟不才。
1 #include<cstdio> 2 #include<iostream> 3 #include<set> 4 #include<map> 5 #include<vector> 6 #include<algorithm> 7 #define int long long 8 #define HZOI using namespace std 9 HZOI; 10 const int MAXN=100003; 11 struct node{ 12 int LX,RX,x,y; 13 friend bool operator < (node a,node b) 14 { 15 return a.x<b.x; 16 } 17 }richer; 18 int n,m,k,ans,xx,yy,flag; 19 char fro1[2],fro2[2]; 20 vector<node> vecL[MAXN<<2],vecR[MAXN<<2]; 21 map<pair<int ,int >,int> mp; 22 inline int read(); 23 void Dfs(int ,int ,char []); 24 signed main() 25 { 26 // freopen("1.out","w",stdout); 27 n=read(); m=read(); k=read(); 28 for (register int i=1,x,y; i<=k; ++i) 29 { 30 richer.x=read(); richer.y=read(); 31 richer.LX=richer.x+richer.y; 32 richer.RX=richer.x-richer.y; 33 vecL[richer.LX+MAXN].push_back(richer); 34 vecR[richer.RX+MAXN].push_back(richer); 35 mp.insert(make_pair(make_pair(richer.x,richer.y),1) ); 36 } 37 for (register int i=1; i<=n; ++i) 38 { 39 richer.x=i,richer.y=0; richer.LX=richer.x+richer.y; richer.RX=richer.x-richer.y; 40 vecL[richer.LX+MAXN].push_back(richer); vecR[richer.RX+MAXN].push_back(richer); 41 mp.insert(make_pair(make_pair(richer.x,richer.y),1) ); 42 richer.y=m+1; richer.LX=richer.x+richer.y; richer.RX=richer.x-richer.y; 43 vecL[richer.LX+MAXN].push_back(richer); vecR[richer.RX+MAXN].push_back(richer); 44 mp.insert(make_pair(make_pair(richer.x,richer.y),1) ); 45 } 46 for (register int i=1; i<=m; ++i) 47 { 48 richer.x=0,richer.y=i; richer.LX=richer.x+richer.y; richer.RX=richer.x-richer.y; 49 vecL[richer.LX+MAXN].push_back(richer); vecR[richer.RX+MAXN].push_back(richer); 50 mp.insert(make_pair(make_pair(richer.x,richer.y),1) ); 51 richer.x=n+1; richer.LX=richer.x+richer.y; richer.RX=richer.x-richer.y; 52 vecL[richer.LX+MAXN].push_back(richer); vecR[richer.RX+MAXN].push_back(richer); 53 mp.insert(make_pair(make_pair(richer.x,richer.y),1) ); 54 } 55 richer.x=0,richer.y=0; richer.LX=richer.x+richer.y; richer.RX=richer.x-richer.y; 56 vecL[richer.LX+MAXN].push_back(richer); vecR[richer.RX+MAXN].push_back(richer); 57 mp.insert(make_pair(make_pair(richer.x,richer.y),1) ); 58 richer.y=m+1; richer.LX=richer.x+richer.y; richer.RX=richer.x-richer.y; 59 vecL[richer.LX+MAXN].push_back(richer); vecR[richer.RX+MAXN].push_back(richer); 60 mp.insert(make_pair(make_pair(richer.x,richer.y),1) ); 61 richer.x=n+1; richer.LX=richer.x+richer.y; richer.RX=richer.x-richer.y; 62 vecL[richer.LX+MAXN].push_back(richer); vecR[richer.RX+MAXN].push_back(richer); 63 mp.insert(make_pair(make_pair(richer.x,richer.y),1) ); 64 richer.y=0; richer.LX=richer.x+richer.y; richer.RX=richer.x-richer.y; 65 vecL[richer.LX+MAXN].push_back(richer); vecR[richer.RX+MAXN].push_back(richer); 66 mp.insert(make_pair(make_pair(richer.x,richer.y),1) ); 67 for (register int i=0; i<=2*MAXN+1; ++i) 68 sort(vecL[i].begin(),vecL[i].end()),sort(vecR[i].begin(),vecR[i].end()); 69 scanf("%lld%lld",&xx,&yy); 70 scanf("%s",fro1); 71 ans=0; 72 node pos,pp; pp.x=xx,pp.y=yy; 73 if (fro1[0]=='S' and fro1[1]=='E') 74 { 75 int _LH=xx-yy+MAXN; 76 int tmp=lower_bound(vecR[_LH].begin(),vecR[_LH].end(),pp)-vecR[_LH].begin(); 77 pos=vecR[_LH][tmp]; 78 xx=pos.x-1; yy=pos.y-1; 79 fro1[0]='N'; fro1[1]='W'; 80 } 81 else if (fro1[0]=='S' and fro1[1]=='W') 82 { 83 int _LH=xx+yy+MAXN; 84 int tmp=lower_bound(vecL[_LH].begin(),vecL[_LH].end(),pp)-vecL[_LH].begin(); 85 pos=vecL[_LH][tmp]; 86 xx=pos.x-1; yy=pos.y+1; 87 fro1[0]='N'; fro1[1]='E'; 88 } 89 else if (fro1[0]=='N' and fro1[1]=='E') 90 { 91 int _LH=xx+yy+MAXN; 92 int tmp=upper_bound(vecL[_LH].begin(),vecL[_LH].end(),pp)-vecL[_LH].begin()-1; 93 pos=vecL[_LH][tmp]; 94 xx=pos.x+1,yy=pos.y-1; 95 fro1[0]='S'; fro1[1]='W'; 96 } 97 else if (fro1[0]=='N' and fro1[1]=='W') 98 { 99 int _LH=xx-yy+MAXN; 100 int tmp=upper_bound(vecR[_LH].begin(),vecR[_LH].end(),pp)-vecR[_LH].begin()-1; 101 pos=vecR[_LH][tmp]; 102 xx=pos.x+1,yy=pos.y+1; 103 fro1[0]='S'; fro1[1]='E'; 104 } 105 flag=0; 106 int x=xx,y=yy; 107 char from[2];from[0]=fro1[0],from[1]=fro1[1]; 108 while (true) 109 { 110 if (x==xx and y==yy and flag) {flag=2;break ;} 111 flag=1; 112 node pp,pos; 113 pp.x=x; pp.y=y; 114 // cout<<"x="<<x<<" y="<<y<<" 方向"<<from[0]<<from[1]<<" ans="<<ans<<endl; 115 if (from[0]=='S' and from[1]=='E') 116 { 117 int _LH=x-y+MAXN; 118 int tmp=lower_bound(vecR[_LH].begin(),vecR[_LH].end(),pp)-vecR[_LH].begin(); 119 pos=vecR[_LH][tmp]; 120 ans+=pos.x-x; 121 if (mp[make_pair(pos.x-1,pos.y)] and !mp[make_pair(pos.x,pos.y-1)]) {from[1]='W'; x=pos.x; y=pos.y-1; continue;} 122 if (!mp[make_pair(pos.x-1,pos.y)] and mp[make_pair(pos.x,pos.y-1)]) {from[0]='N'; x=pos.x-1; y=pos.y; continue;} 123 break ; 124 } 125 if (from[0]=='S' and from[1]=='W') 126 { 127 int _LH=x+y+MAXN; 128 int tmp=lower_bound(vecL[_LH].begin(),vecL[_LH].end(),pp)-vecL[_LH].begin(); 129 pos=vecL[_LH][tmp]; 130 ans+=pos.x-x; 131 if (mp[make_pair(pos.x-1,pos.y)] and !mp[make_pair(pos.x,pos.y+1)]) {from[1]='E'; x=pos.x; y=pos.y+1; continue;} 132 if (!mp[make_pair(pos.x-1,pos.y)] and mp[make_pair(pos.x,pos.y+1)]) {from[0]='N'; x=pos.x-1; y=pos.y; continue;} 133 break ; 134 } 135 if (from[0]=='N' and from[1]=='E') 136 { 137 int _LH=x+y+MAXN; 138 int tmp=upper_bound(vecL[_LH].begin(),vecL[_LH].end(),pp)-vecL[_LH].begin()-1; 139 pos=vecL[_LH][tmp]; 140 ans+=x-pos.x; 141 if (mp[make_pair(pos.x+1,pos.y)] and !mp[make_pair(pos.x,pos.y-1)]) {from[1]='W'; x=pos.x; y=pos.y-1; continue;} 142 if (!mp[make_pair(pos.x+1,pos.y)] and mp[make_pair(pos.x,pos.y-1)]) {from[0]='S'; x=pos.x+1; y=pos.y; continue;} 143 break ; 144 } 145 if (from[0]=='N' and from[1]=='W') 146 { 147 int _LH=x-y+MAXN; 148 int tmp=upper_bound(vecR[_LH].begin(),vecR[_LH].end(),pp)-vecR[_LH].begin()-1; 149 pos=vecR[_LH][tmp]; 150 ans+=x-pos.x; 151 if (mp[make_pair(pos.x+1,pos.y)] and !mp[make_pair(pos.x,pos.y+1)]) {from[1]='E'; x=pos.x; y=pos.y+1; continue;} 152 if (!mp[make_pair(pos.x+1,pos.y)] and mp[make_pair(pos.x,pos.y+1)]) {from[0]='S'; x=pos.x+1; y=pos.y; continue;} 153 break ; 154 } 155 break ; 156 } 157 if (flag==2) {printf("%lld",ans);return 0;} 158 // cout<<"ppppppppppppppppp"<<endl; 159 flag=0; 160 if (fro1[0]=='S') fro2[0]='N'; 161 else fro2[0]='S'; 162 if (fro1[1]=='E') fro2[1]='W'; 163 else fro2[1]='E'; 164 from[0]=fro2[0]; from[1]=fro2[1]; 165 x=xx; y=yy; 166 while (true) 167 { 168 if (x==xx and y==yy and flag) {flag=2;break ;} 169 flag=1; 170 node pp,pos; 171 pp.x=x; pp.y=y; 172 // cout<<"x="<<x<<" y="<<y<<" 方向"<<from[0]<<from[1]<<" ans="<<ans<<endl; 173 if (from[0]=='S' and from[1]=='E') 174 { 175 int _LH=x-y+MAXN; 176 int tmp=lower_bound(vecR[_LH].begin(),vecR[_LH].end(),pp)-vecR[_LH].begin(); 177 pos=vecR[_LH][tmp]; 178 ans+=pos.x-x; 179 if (mp[make_pair(pos.x-1,pos.y)] and !mp[make_pair(pos.x,pos.y-1)]) {from[1]='W'; x=pos.x; y=pos.y-1; continue;} 180 if (!mp[make_pair(pos.x-1,pos.y)] and mp[make_pair(pos.x,pos.y-1)]) {from[0]='N'; x=pos.x-1; y=pos.y; continue;} 181 break ; 182 } 183 if (from[0]=='S' and from[1]=='W') 184 { 185 int _LH=x+y+MAXN; 186 int tmp=lower_bound(vecL[_LH].begin(),vecL[_LH].end(),pp)-vecL[_LH].begin(); 187 pos=vecL[_LH][tmp]; 188 ans+=pos.x-x; 189 if (mp[make_pair(pos.x-1,pos.y)] and !mp[make_pair(pos.x,pos.y+1)]) {from[1]='E'; x=pos.x; y=pos.y+1; continue;} 190 if (!mp[make_pair(pos.x-1,pos.y)] and mp[make_pair(pos.x,pos.y+1)]) {from[0]='N'; x=pos.x-1; y=pos.y; continue;} 191 break ; 192 } 193 if (from[0]=='N' and from[1]=='E') 194 { 195 int _LH=x+y+MAXN; 196 int tmp=upper_bound(vecL[_LH].begin(),vecL[_LH].end(),pp)-vecL[_LH].begin()-1; 197 pos=vecL[_LH][tmp]; 198 ans+=x-pos.x; 199 if (mp[make_pair(pos.x+1,pos.y)] and !mp[make_pair(pos.x,pos.y-1)]) {from[1]='W'; x=pos.x; y=pos.y-1; continue;} 200 if (!mp[make_pair(pos.x+1,pos.y)] and mp[make_pair(pos.x,pos.y-1)]) {from[0]='S'; x=pos.x+1; y=pos.y; continue;} 201 break ; 202 } 203 if (from[0]=='N' and from[1]=='W') 204 { 205 int _LH=x-y+MAXN; 206 int tmp=upper_bound(vecR[_LH].begin(),vecR[_LH].end(),pp)-vecR[_LH].begin()-1; 207 pos=vecR[_LH][tmp]; 208 ans+=x-pos.x; 209 if (mp[make_pair(pos.x+1,pos.y)] and !mp[make_pair(pos.x,pos.y+1)]) {from[1]='E'; x=pos.x; y=pos.y+1; continue;} 210 if (!mp[make_pair(pos.x+1,pos.y)] and mp[make_pair(pos.x,pos.y+1)]) {from[0]='S'; x=pos.x+1; y=pos.y; continue;} 211 break ; 212 } 213 break ; 214 } 215 printf("%lld",ans-1); 216 return 0; 217 } 218 inline int read() 219 { 220 int num=0; char ch=getchar(); 221 while (ch<'0' or ch>'9') ch=getchar(); 222 while (ch>='0' and ch<='9') num=(num<<3)+(num<<1)+(ch^48),ch=getchar(); 223 return num; 224 }
永不放弃。