Atcoder Grand Contest 021 題解
Problem A. (此處省略)反正怎麼搞都行了。。。
Problem B. 對於每個點,列舉其他點,那麼選的點一定是在垂直平分線的一側。由於R 特別大,所以可以把這個垂直平分線移到這個點上,就相當於一堆可行極角區間求交
也可以
#include<bits/stdc++.h>
#define maxn 110
using namespace std;
typedef double ldb;
const ldb eps=1e-7;
const ldb pi=acos(-1.0);
ldb nx[maxn],ny[maxn];
int n;
int dcmp(ldb d){
return fabs(d)<eps?0:(d<0?-1:1);
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;++i)
scanf("%lf%lf",&nx[i],&ny[i]);
for(int i=1;i<=n;++i){
ldb mn=0,mx=pi;
int id=(i==1?2:1);
ldb ang=atan2(ny[id]-ny[i],nx[id]-nx[i]);
for (int j=1;j<=n;++j)if(i!=j&&j!=id){
ldb ang1=atan2(ny[j]-ny[i],nx[j]-nx[i]);
ldb a=ang-ang1;
if(dcmp(a-pi)==0||dcmp(a+pi)==0)mn=1e20;
if(dcmp(a-pi)>0)a-=2*pi;
else if(dcmp(-pi-a)>0)a+=2*pi;
if(dcmp(a)<0)mn=max(mn,-a);
else mx=min(mx,pi-a);
}
// printf("[%.3lf,%.3lf]",mn,mx);
if(dcmp(mn-mx)>=0)puts("0.0");
else printf("%.10lf\n",(mx-mn)/(2*pi));
}
}
Problem C.可以發現,一定是先貪心放2*2的小方塊,多的部分用一種方塊來補。最後要特判右下角的3*3方格。
#include<bits/stdc++.h>
using namespace std;
char s[1010][1010];
int n,m,a,b;
int main(){
scanf("%d%d%d%d",&n,&m,&a,&b);
for(int i=1;i<=n;++i)for(int j=1;j<=m;++j)s[i][j]='.';
if(n&1)for(int i=1;i<m&&a;i+=2)s[n][i]='<',s[n][i+1]='>',a--;
if(m&1)for(int i=1;i<n&&b;i+=2)s[i][m]='^',s[i+1][m]='v',b--;
for(int i=1;i<n;i+=2)
for(int j=1;j<m;j+=2){
if(a>=2){
a-=2;
s[i][j]='<',s[i][j+1]='>';
s[i+1][j]='<',s[i+1][j+1]='>';
} else if(b>=2){
b-=2;
s[i][j]='^',s[i][j+1]='^';
s[i+1][j]='v',s[i+1][j+1]='v';
} else if(a&&b&&i==n-2&&j==m-2){
a--,b--;
s[i][j]='<',s[i][j+1]='>',s[i][j+2]='^';
s[i+1][j]='^',s[i+1][j+2]='v';
s[i+2][j]='v',s[i+2][j+1]='<',s[i+2][j+2]='>';
} else if(a){
a--;
s[i][j]='<',s[i][j+1]='>';
} else if(b){
b--;
s[i][j]='^',s[i+1][j]='v';
}
}
if(a||b)return puts("NO"),0;
puts("YES");
for(int i=1;i<=n;++i)puts(s[i]+1);
}
Problem D.直接
#include<bits/stdc++.h>
using namespace std;
int dp[310][310][310],n;
char s[310];
int dfs(int l,int r,int k){
if(k<0)return -1000000007;
if(l>r)return 0;
else if(l==r)return 1;
if(~dp[l][r][k])return dp[l][r][k];
dp[l][r][k]=max(dfs(l+1,r,k),dfs(l,r-1,k));
dp[l][r][k]=max(dp[l][r][k],dfs(l+1,r-1,k-(s[l]!=s[r]))+2);
// printf("{%d,%d,%d,%d}",l,r,k,dp[l][r][k]);
return dp[l][r][k];
}
int main(){
memset(dp,-1,sizeof(dp));
scanf("%s%d",s+1,&n);
printf("%d\n",dfs(1,strlen(s+1),n));
}
Problem E.
首先R< B肯定不可行。
可以發現,一個可行的方案一定滿足R-B+match≤n,其中match表示R,B最大匹配數。
假設我們把這個序列理解為平面上(0,0)到(R,B)的一個路徑,設現在在(x,y)
當R>B,y>x時若要滿足條件,一定有R-B+x+min(B-y,R-x)≤n
即不能有y-x≤R-n+1
R=B同理。
考慮如何算這個,可以用反射法,就是到這個直線就開始分成2條路徑。詳細看官方題解。
#include<bits/stdc++.h>
#define maxn 1001000
#define mod 998244353
using namespace std;
int fac[maxn],inv[maxn],n,m,K,M;
int qpow(int a,int b){
int ans=1,tmp=a;
for(;b;b>>=1,tmp=1ll*tmp*tmp%mod)
if(b&1)ans=1ll*ans*tmp%mod;
return ans;
}
int C(int x,int y){
if(x>y||x<0)return 0;
return 1ll*fac[y]*inv[x]%mod*inv[y-x]%mod;
}
int main(){
scanf("%d%d",&n,&K),M=K,fac[0]=inv[0]=1;
for(int i=1;i<=M;++i)fac[i]=1ll*fac[i-1]*i%mod;
inv[M]=qpow(fac[M],mod-2);
for(int i=M-1;i>=1;--i)inv[i]=1ll*inv[i+1]*(i+1)%mod;
int ans=0;
for(int i=0;i<=K-i;++i){
int r=K-i,b=i;
if(r-b+min(r,b)<n)continue;
if(r>b)ans=(1ll*ans+C(r,r+b)-C(r+r-n+1,r+b)+mod)%mod;
else ans=(1ll*ans+C(r,r+b-1)-C(r+b-n+1,r+b-1)+mod)%mod;
}
printf("%d\n",ans);
}
Problem F.令dp[i][j]表示i列j行的圖的答案,且這j行非空。則有如下轉移:
1.dp[i][j]->dp[i+1][j],此時有1+C(j,1)+C(j,2)種方案。
2.dp[i][j]->dp[i+1][j+k](k>1),此時只需要考慮新列的方案數,如果最大值放在了j行中的一個,可以將這一行視為新建行,否則可以將最大值多取一個,反正可以發現答案就是i+k+2中選k+2個,即C(i+k+2,k+2)
然後發現這是個卷積的形式。完了。複雜度
#include<bits/stdc++.h>
#define mod 998244353
#define maxn 8200
using namespace std;
typedef long long ll;
int n,m,dp[210][maxn<<1],wn[2][maxn<<1],bh[maxn<<1];
int A[maxn<<1],M,fac[maxn<<1],k,inv[maxn<<1];
int qpow(int a,int b){
int ans=1;
for(;b;b>>=1,a=1ll*a*a%mod)
if(b&1)ans=1ll*ans*a%mod;
return ans;
}
void init(){
for(int i=1,p;i<M;i<<=1){
wn[0][i]=1,p=qpow(3,(mod-1)/(i<<1));
for(int j=1;j<i;++j)wn[0][i+j]=(ll)wn[0][i+j-1]*p%mod;
wn[1][i]=1,p=qpow(3,mod-1-(mod-1)/(i<<1));
for(int j=1;j<i;++j)wn[1][i+j]=(ll)wn[1][i+j-1]*p%mod;
}
}
void fft(int h[],int len,int flag){
for(int i=0;i<len;++i)if(i<bh[i])swap(h[i],h[bh[i]]);
for(int i=1;i<len;i<<=1)
for(int j=0;j<len;j+=(i<<1))
for(int k=0;k<i;++k){
int x=h[j+k],y=(ll)h[j+k+i]*wn[flag][i+k]%mod;
h[j+k]=(x+y)%mod,h[j+k+i]=(x-y+mod)%mod;
}
if(flag==1){
int iv=qpow(len,mod-2);
for(int i=0;i<len;++i)h[i]=1ll*h[i]*iv%mod;
}
}
int C(int x,int y){
if(x>y||x<0)return 0;
return (ll)fac[y]*inv[x]%mod*inv[y-x]%mod;
}
int main(){
scanf("%d%d",&n,&m),M=1,k=0,fac[0]=inv[0]=1;
while(M<2*n)M<<=1,k++;
for(int i=1;i<=n+2;++i)fac[i]=1ll*fac[i-1]*i%mod;
inv[n+2]=qpow(fac[n+2],mod-2);
for(int i=n+1;i>=1;--i)inv[i]=1ll*inv[i+1]*(i+1)%mod;
for(int i=0;i<M;++i)bh[i]=(bh[i>>1]>>1)|((i&1)<<(k-1));
init();
dp[0][0]=1;
for(int i=0;i<m;++i){
for(int j=0;j<=n;++j)
dp[i+1][j]=(ll)(j*(j+1)/2+1)*dp[i][j]%mod,
dp[i][j]=(ll)dp[i][j]*inv[j]%mod;
for(int j=0;j<=M;++j)A[j]=0;
for(int j=1;j<=n;++j)A[j]=inv[j+2];
fft(dp[i],M,0),fft(A,M,0);
for(int j=0;j<M;++j)A[j]=(ll)A[j]*dp[i][j]%mod;
fft(A,M,1);
for(int j=1;j<=n;++j)
dp[i+1][j]=(dp[i+1][j]+(ll)A[j]*fac[j+2])%mod;
}
int ans=0;
// for(int i=0;i<=n;++i)printf("[%d]",dp[m][i]);
for(int i=0;i<=n;++i)ans=(ans+(ll)C(i,n)*dp[m][i])%mod;
printf("%d",ans);
}
相關推薦
Atcoder Grand Contest 021 題解
Problem A. (此處省略)反正怎麼搞都行了。。。 Problem B. 對於每個點,列舉其他點,那麼選的點一定是在垂直平分線的一側。由於R 特別大,所以可以把這個垂直平分線移到這個點上,就相當於一堆可行極角區間求交 也可以O(nlogn),大概是把凸
Atcoder Grand Contest 002 題解
push_back 個人選擇 first box 可能 getc 等於 clear const A - Range Product 經過0答案肯定是0,都是正數肯定是正數,都是負數的話就奇負偶正。 //waz #include <bits/stdc++.h>
Atcoder Grand Contest 003 題解
位置 發現 clu cpp 模擬 gii icu define -a A - Wanna go back home 如果有S就必須要有N,反之亦然,如果有E必須要有W,反之亦然。判斷一下就好了。 //waz #include <bits/stdc++.h>
AtCoder Grand Contest 013 題解
fine esp square == ask air %d nis 就是 A - Sorted Arrays 貪心,看看不下降和不上升最長能到哪,直接轉移過去即可。 1 //waz 2 #include <bits/stdc++.h> 3 4 us
AtCoder Grand Contest 015 題解
pan gin ken -- 出現 style 地方 連通塊 發現 A - A+...+B Problem 可以取到的值一定是一段區間。所以答案即為max-min+1 1 //waz 2 #include <bits/stdc++.h> 3 4 u
[atcoder]AtCoder Grand Contest 027題解
【題目連結】 A 【題解】 題意: 是把xxx個糖果分給nnn個人,一個人如果恰好分到aia_{i}ai個糖果就會高興。求最多使多少個人高興。 題解: 一定是優先滿足需求小的人,特判有額外的剩餘糖果。 時間複雜度:O(NlogN)O(NlogN)O(Nlog
AtCoder Grand Contest 031 簡要題解
isp href uil 出現 mat false tor 每次 spa AtCoder Grand Contest 031 Atcoder A - Colorful Subsequence description 求\(s\)中本質不同子序列的個數模\(10^9+7\)。
AtCoder Grand Contest 013D: Piling Up 題解
情況 之前 include out fin fine del ons etc 題意簡化: [luogu] Piling Up 一開始有n個顏色為黑白的球,但不知道黑白色分別有多少,m次操作,每次先拿出一個球,再放入黑白球各一個,再拿出一個球,最後拿出的球按順序排列會形成一個
AtCoder Grand Contest 020 C - Median Sum
CI https TE ems and fin sub oot tco 題目:here 題解:要轉化一下,找所有子集的中間值,等價於找一個子集,滿足這個子集的和最接近整個序列的和的一半。也就是一個背包判斷可行性的問題。重點來了,bitset優化,至於為什麽?我也不懂啊啊啊
[Atcoder Grand Contest 001] Tutorial
IV AI display aps span col tin lap nbsp Link: AGC001 傳送門 A: #include <bits/stdc++.h> using namespace std; long long res=0; int n
AtCoder Grand Contest 024 Problem E(動態規劃)
stand 之間 graph ret scan 慢慢 rap and there www.cnblogs.com/shaokele/ AtCoder Grand Contest 024 Problem E Time Limit: 2 Sec Memory Lim
AtCoder Grand Contest 006 F - Blackout
sin 所在 long long || 如果 open int 雙向 mem Description 在 \(n*n\) 的棋盤上給出 \(m\) 個黑點,若 \((x,y)\),\((y,z)\) 都是黑點,那麽 \((z,x)\) 也會變成黑點,求最後黑點的數量 題面
AtCoder Grand Contest #026 C - String Coloring
暴力 input 很好 left rgs map() paint int() letters Time Limit: 3 sec / Memory Limit: 1024 MB Score : 600600 points Problem Statement Y
AtCoder Grand Contest 007
mem ssi || 狀態 puts def end tor ace AtCoder Grand Contest 007 A - Shik and Stone 翻譯 見洛谷 題解 傻逼玩意 #include<cstdio> int n,m,tot;char ch
AtCoder Regular Contest 103 題解
print -s struct namespace type iostream con clas inline C-/\/\/\ #include<algorithm> #include<iostream> #include<cstdlib&g
AtCoder Grand Contest 011
判斷 define 開機 %s square d+ 更新 getc 在一起 AtCoder Grand Contest 011 upd:這篇咕了好久,前面幾題是三周以前寫的。。。 AtCoder Grand Contest 011 A - Airport Bus 翻譯 有\
AtCoder Grand Contest 001 C Shorten Diameter 樹的直徑
題意 給你一棵樹,每次可以刪除一個葉子節點,求最少需要多少次操作可以讓樹的直徑\(<=k,(n <= 2e3)\) 首先觀察資料範圍是可以接受\(O(n^2)\)的演算法的 我們考慮列舉每個點作為樹的根 統計這個點一定在直徑上時要刪多少點 如果\(k\)是偶數,那麼深度大於\(
AtCoder Grand Contest 006 C:Rabbit Exercise
題目傳送門:https://agc006.contest.atcoder.jp/tasks/agc006_c 題目翻譯 數軸上有\(N\)只兔子,從\(1\)到\(N\)編號,每隻兔子初始位置是\(x_i\)。現在兔子們要開始做運動,運動都有\(M\)個步驟,對於第\(i\)個步驟,我們用\(a_i\)來
AtCoder Grand Contest 014 E:Blue and Red Tree
make 開始 n-1 不可 task blog 應該 space find 題目傳送門:https://agc014.contest.atcoder.jp/tasks/agc014_e 題目翻譯 有一棵有\(N\)個點的樹,初始時每條邊都是藍色的,每次你可以選擇一條由藍色
AtCoder Grand Contest 012 D:Colorful Balls
題目傳送門:https://agc012.contest.atcoder.jp/tasks/agc012_d 題目翻譯 給你一排一共\(N\)個球,每個球有一個顏色\(c_i\)和一個重量\(w_i\),如果兩個球顏色相同,重量相加不超過\(x\)那我就可以交換這倆個球的位置。如果兩個球顏色不同,重量相加