Tags:題解ios
link:https://atcoder.jp/contests/exawizards2019
很水的一場ARC啊,隨隨便便就ABCDE了,F最後想到了尚未寫出來。
D題花了過久時間因此只有Rank31,我是真的菜。
嘿嘿嘿,上述裝逼方式是我最爲反感的機房裏的言語,既然快退役了,也就學一學,感覺一下機房裏dalao們怎麼樣裝逼一時爽、一直裝逼一直爽,聽者一時喪,一直聽一直喪的快感咯spa
有意思的題應該是DE了。code
若是三個數相等輸出Yes
,不然No
。排序
#include<iostream> using namespace std; int main() { int A,B,C; cin>>A>>B>>C; if(A==B&&B==C) puts("Yes"); else puts("No"); }
字符串中R
個數超過一半輸出Yes
,不然No
。ci
#include<iostream> using namespace std; int n,a; char s[1000000]; int main() { cin>>n; scanf("%s",s+1); for(int i=1;i<=n;i++) if(s[i]=='R') a++; if(a*2>n) puts("Yes"); else puts("No"); }
一排格子,每一個格子有一個屬性,用小寫字母表示。
初始每一個格子上都有一枚硬幣,Q次操做形如某種屬性的格子上的硬幣所有左移或右移一位。
移出邊界就消失,問最後剩餘硬幣數。字符串
發現移出去的必定是一段前綴和一段後綴,具備可二分性。get
#include<iostream> using namespace std; const int N=2e5+10; int n,Q; char s[N],t[N],d[N]; int Drop(int x) { for(int i=1;i<=Q;i++) { if(s[x]==t[i]) x+=(d[i]=='R')?1:-1; if(x>n) return -1; if(x<1) return 1; } return 0; } int main() { cin>>n>>Q; scanf("%s",s+1); for(int i=1;i<=Q;i++) cin>>t[i]>>d[i]; int l=1,r=n,la=0,ra=n+1; while(l<=r) { int mid=(l+r)>>1; if(Drop(mid)==1) la=mid,l=mid+1; else r=mid-1; } l=1,r=n; while(l<=r) { int mid=(l+r)>>1; if(Drop(mid)==-1) ra=mid,r=mid-1; else l=mid+1; } cout<<ra-la-1<<endl; }
給一個長度爲\(n\)的數列和\(X\),對於一種排列,其權值爲X依次對排列中的數取模、最後剩下的值。
問\(n!\)種狀況的權值和。\(n\le 200,X\le 10^5\)it
詳見UOJ22。有一個性質就是大的數排在小的數的後面,則那個大數沒有影響。
因此從大往小排序後依次作。設\(f[i][j]\)表示作了\(i\)次操做,剩餘數爲\(j\)的方案數。
轉移有兩種:io
即若是選了這個數則必須放在這一位,不然能夠放在後面\(n-i\)個數的任意一位。class
#include<iostream> #include<algorithm> using namespace std; const int N=1e5+10,mod=1e9+7; int n,X,f[N],Ans,g[N],s[N]; int cmp(int a,int b) {return a>b;} int main() { cin>>n>>X; f[X]=1; for(int i=1;i<=n;i++) cin>>s[i]; sort(s+1,s+n+1,cmp); for(int i=1,x;i<=n;i++) { x=s[i]; for(int j=0;j<=X;j++) g[j]=0; for(int j=0;j<=X;j++) { (g[j%x]+=f[j])%=mod; (g[j]+=1ll*f[j]*(n-i)%mod)%=mod; } for(int j=0;j<=X;j++) f[j]=g[j]; } for(int j=0;j<=X;j++) (Ans+=1ll*f[j]*j%mod)%=mod; cout<<Ans<<endl; }
有一些黑球和白球,若是兩種球都有則各有一半的概率取出,不然必定取出剩下的那種顏色的求。
對於\(i\le 2e5\),求第\(i\)次拿到黑球的機率。
令前\(i\)次把白球拿完的機率是\(T_w\),把黑球拿完的機率是\(T_b\),則第\(i+1\)次取出黑球的機率是\(T_w+(1-T_W-T_b)*\frac{1}{2}\)。
轉成在剛好第\(i\)次拿完白球的機率\(g_i=2^{i}{i-1 \choose W-1}\),\(W\)爲白球總數。
#include<iostream> using namespace std; const int N=2e5+10,mod=1e9+7; int jc[N],inv[N],bit[N],B,W,sw[N],sb[N]; int ksm(int x,int k) { int s=1;for(;k;k>>=1,x=1ll*x*x%mod) if(k&1) s=1ll*s*x%mod;return s; } int C(int n,int k) {return 1ll*jc[n]*inv[k]%mod*inv[n-k]%mod;} int main() { cin>>B>>W; jc[0]=bit[0]=inv[0]=1; for(int i=1;i<=B+W;i++) jc[i]=1ll*i*jc[i-1]%mod; for(int i=1;i<=B+W;i++) inv[i]=ksm(jc[i],mod-2); for(int i=1;i<=B+W;i++) bit[i]=1ll*bit[i-1]*inv[2]%mod; for(int i=W;i<B+W;i++) sw[i]=1ll*bit[i]*C(i-1,i-W)%mod; for(int i=B;i<B+W;i++) sb[i]=1ll*bit[i]*C(i-1,i-B)%mod; for(int i=1;i<=B+W;i++) { (sw[i]+=sw[i-1])%=mod; (sb[i]+=sb[i-1])%=mod; } for(int i=1;i<=B+W;i++) { int w=(sw[i-1]+1ll*((mod+1-sw[i-1]-sb[i-1])%mod+mod)%mod* (i==B+W?1:inv[2])%mod)%mod; cout<<w<<endl; } }
給你一張網格圖,同一行或同一列的邊的方向都同樣,求多組詢問,問兩點之間的最短路。
發現有用的邊就只有距離起點終點四個方向最近的兩條邊,一共16條邊,把交點摳出來跑最短路就行了。
個人實現方式要3700ms,租酥雨只要跑970ms真的牆。
#include<iostream> #include<algorithm> #include<queue> #include<set> using namespace std; const int N=2e5+10,mod=1e9+7; int n,m,q,Ans,HH[N],ZZ[N],dis[N],vis[N]; char s[N],t[N]; set<int> H[2],Z[2]; queue<int> Q; struct Node{int x,y;}P[N]; void GetAns(int x1,int y1,int x2,int y2) { int ch=0,cz=0,c=0; set<int>::iterator it; for(int i=0;i<2;i++) { it=H[i].lower_bound(x1); if(it!=H[i].end()) HH[++ch]=*it; if(it!=H[i].begin()) HH[++ch]=*(--it); it=H[i].lower_bound(x2); if(it!=H[i].end()) HH[++ch]=*it; if(it!=H[i].begin()) HH[++ch]=*(--it); it=Z[i].lower_bound(y1); if(it!=Z[i].end()) ZZ[++cz]=*it; if(it!=Z[i].begin()) ZZ[++cz]=*(--it); it=Z[i].lower_bound(y2); if(it!=Z[i].end()) ZZ[++cz]=*it; if(it!=Z[i].begin()) ZZ[++cz]=*(--it); } sort(HH+1,HH+ch+1); ch=unique(HH+1,HH+ch+1)-HH-1; sort(ZZ+1,ZZ+cz+1); cz=unique(ZZ+1,ZZ+cz+1)-ZZ-1; for(int i=1;i<=ch;i++) for(int j=1;j<=cz;j++) P[++c]=(Node){HH[i],ZZ[j]}; for(int i=1;i<=c;i++) if(P[i].x==x1&&P[i].y==y1) dis[i]=0,Q.push(i),vis[i]=1; else dis[i]=1e9; while(!Q.empty()) { int x=Q.front(); for(int i=1;i<=c;i++) { if(P[i].x!=P[x].x&&P[i].y!=P[x].y) continue; if(P[i].x==P[x].x) { if(P[i].y>P[x].y&&s[P[i].x]=='W') continue; if(P[i].y<P[x].y&&s[P[i].x]=='E') continue; } if(P[i].y==P[x].y) { if(P[i].x>P[x].x&&t[P[i].y]=='N') continue; if(P[i].x<P[x].x&&t[P[i].y]=='S') continue; } int val=dis[x]+abs(P[i].x-P[x].x)+abs(P[i].y-P[x].y); if(dis[i]<=val) continue; dis[i]=val; if(!vis[i]) Q.push(i),vis[i]=1; } Q.pop(),vis[x]=0; } for(int i=1;i<=c;i++) if(P[i].x==x2&&P[i].y==y2) Ans=dis[i]; } int main() { scanf("%d%d%d%s%s",&n,&m,&q,s+1,t+1); for(int i=1;i<=n;i++) if(s[i]=='E') H[1].insert(i); else H[0].insert(i); for(int i=1;i<=m;i++) if(t[i]=='N') Z[1].insert(i); else Z[0].insert(i); for(int i=1,x1,y1,x2,y2;i<=q;i++) { cin>>x1>>y1>>x2>>y2; GetAns(x1,y1,x2,y2); if(Ans==1e9) puts("-1"); else printf("%d\n",Ans); } return 0; }