Wannafly挑戰賽27
Wannafly挑戰賽27
我打的第一場$Wannafly$是第25場,$T2$竟然出了一個幾何題?而且還把我好不容易升上綠的$Rating$又降回了藍名...之後再不敢打$Wannafly$了.
由於某一場比賽打了一半就咕咕咕了,現在$Rating$已經降得很低了,幹脆打一場碰碰運氣好了.
差六名就抽到我發獎品了,就當攢點$rp$給聯賽好了.
T1:http://www.nowcoder.com/acm/contest/215/A
題意概述:給出長度為$n$的序列, 求有多少對數對 $(i,j)(1<=i<j<=n)$ 滿足 $a_i+a_j$為完全平方數。$n,a_i<=10^5$
這次的簽到題還是很簡單的,$N^2$暴力實在是太假了,但是可以發現數據範圍內的完全平方數並不是很多,開一個桶記錄之前出現過數的次數,每讀入一個數就枚舉範圍內所有完全平方數進行判斷即可.(註意數組下標不能為負)
1 # include <cstdio> 2 # include <iostream> 3 # include <cstring> 4 # include <algorithm> 5 # include <string> 6 # include <cmath> 7 # define R register int灰魔法師8 # define ll long long 9 10 using namespace std; 11 12 const int maxn=100005; 13 int n; 14 int a[maxn]; 15 int h,t[maxn+5]; 16 ll q[maxn],ans; 17 18 int main() 19 { 20 scanf("%d",&n); 21 ll i=0; 22 while (1) 23 { 24 q[++h]=i*i; 25 i++; 26 if(i*i>=200005) break; 27 } 28 for (R i=1;i<=n;++i) 29 { 30 scanf("%d",&a[i]); 31 for (R j=1;j<=h;++j) 32 { 33 if(a[i]>q[j]) continue; 34 if(q[j]-a[i]<=maxn) ans+=t[ q[j]-a[i] ]; 35 } 36 t[ a[i] ]++; 37 } 38 printf("%lld",ans); 39 return 0; 40 }
T2:http://www.nowcoder.com/acm/contest/215/B
題意概述:給定一棵仙人掌,求最少用多少顏色可以對其染色,一條邊連接的兩個點不能染相同的染色.$n<=10^5,m<=2 \times 10^5$
仙人掌?圖的色數?我記得這不是一個$NP$完全問題嗎?
然而...一個圖必須至少使用$n$種顏色才能染色的一個條件是至少存在$n$個點構成一張完全圖,對於仙人掌來說,最多出現一個$3$個點構成的環使得色數為$3$,大於等於$4$的情況根本不存在。
判斷答案是否為$1$:沒有邊答案就是$1$;
判斷答案是否為$2$:黑白染色判斷即可.
判斷答案是否為$3$:找三元環看起來非常麻煩,雖然傳說中有一種$O(M\sqrt{N})$的做法,但是...不是$1$又不是$2$不就是三了嗎?
1 # include <cstdio> 2 # include <iostream> 3 # include <cstring> 4 # include <algorithm> 5 # include <string> 6 # include <cmath> 7 # define R register int 8 9 using namespace std; 10 11 const int maxn=100005; 12 const int maxm=200005; 13 int n,m,x,y,h,f; 14 int firs[maxn],vis[maxn]; 15 struct edge 16 { 17 int too,nex; 18 }g[maxm<<1]; 19 20 void add (int x,int y) 21 { 22 g[++h].too=y; 23 g[h].nex=firs[x]; 24 firs[x]=h; 25 } 26 27 void dfs (int x) 28 { 29 int j; 30 for (R i=firs[x];i;i=g[i].nex) 31 { 32 j=g[i].too; 33 if(vis[j]&&vis[j]==vis[x]) f=1; 34 if(vis[j]) continue; 35 if(vis[x]==1) vis[j]=2; 36 if(vis[x]==2) vis[j]=1; 37 dfs(j); 38 } 39 } 40 41 int main() 42 { 43 scanf("%d%d",&n,&m); 44 if(m==0) 45 { 46 printf("1"); 47 return 0; 48 } 49 for (R i=1;i<=m;++i) 50 { 51 scanf("%d%d",&x,&y); 52 add(x,y); 53 add(y,x); 54 } 55 vis[1]=1; 56 dfs(1); 57 if(f) printf("3"); 58 else printf("2"); 59 return 0; 60 }紫魔法師
T3:http://www.nowcoder.com/acm/contest/215/C
題意概述:將一棵樹刪去一些邊使得每個聯通塊的大小$<=k$的方案數.$k<=n<=2000$
看上去像是個樹形$dp$,$dp[i][j]$表示以$i$為根的子樹中保留$i$,根處的聯通塊大小為$j$的方案數,慢慢轉移就好.
當然不行啦!慢慢轉移就$TLE$了!你需要的是快快轉移.
$asuldb$和$zutter$兩位大佬一同表示樹上背包的復雜度是$O(NK)$,我還以為我記錯了,直到我造了一棵掃帚樹...
現在的復雜度是$O(TLE)$,但是聽說牛客的機器能跑$10^{10}$,就開始了漫長的卡常之旅,首先肯定是一些最簡單的$register,inline$,轉移的時候只轉移到子樹大小(掃帚樹就是專門卡這個的),後來加上了這個:
1 inline char gc() 2 { 3 static char now[1<<22],*S,*T; 4 if (T==S) 5 { 6 T=(S=now)+fread(now,1,1<<22,stdin); 7 if (T==S) return EOF; 8 } 9 return *S++; 10 } 11 inline int read() 12 { 13 R x=0; 14 register char ch=gc(); 15 while(!isdigit(ch)) 16 ch=gc(); 17 while(isdigit(ch)) x=(x<<1)+(x<<3)+ch-‘0‘,ch=gc(); 18 return x; 19 }神仙快讀
這個:
1 inline int ad (int a,int b) 2 { 3 a+=b; 4 if(a>=mod) a-=mod; 5 return a; 6 }加法取模優化
把所有的$long$ $long$換成$int$;
如果乘法中有一項已經是$0$就不乘了;
然而結果依然是:
正當大家紛紛退出卡常大賽的時候,我突然想起之前看$pks$的博客中提到的毒瘤優化,試了一下發現在本機編譯都過不了,但是嘗試了一下"自測",發現牛客網能編譯這個!於是就愉快的過掉了這道題.下面是我已經看不大懂的代碼.
1 #pragma GCC diagnostic error "-std=c++14" 2 #pragma GCC target("avx") 3 #pragma GCC optimize(3) 4 #pragma GCC optimize("Ofast") 5 #pragma GCC optimize("inline") 6 #pragma GCC optimize("-fgcse") 7 #pragma GCC optimize("-fgcse-lm") 8 #pragma GCC optimize("-fipa-sra") 9 #pragma GCC optimize("-ftree-pre") 10 #pragma GCC optimize("-ftree-vrp") 11 #pragma GCC optimize("-fpeephole2") 12 #pragma GCC optimize("-ffast-math") 13 #pragma GCC optimize("-fsched-spec") 14 #pragma GCC optimize("unroll-loops") 15 #pragma GCC optimize("-falign-jumps") 16 #pragma GCC optimize("-falign-loops") 17 #pragma GCC optimize("-falign-labels") 18 #pragma GCC optimize("-fdevirtualize") 19 #pragma GCC optimize("-fcaller-saves") 20 #pragma GCC optimize("-fcrossjumping") 21 #pragma GCC optimize("-fthread-jumps") 22 #pragma GCC optimize("-funroll-loops") 23 #pragma GCC optimize("-fwhole-program") 24 #pragma GCC optimize("-freorder-blocks") 25 #pragma GCC optimize("-fschedule-insns") 26 #pragma GCC optimize("inline-functions") 27 #pragma GCC optimize("-ftree-tail-merge") 28 #pragma GCC optimize("-fschedule-insns2") 29 #pragma GCC optimize("-fstrict-aliasing") 30 #pragma GCC optimize("-fstrict-overflow") 31 #pragma GCC optimize("-falign-functions") 32 #pragma GCC optimize("-fcse-skip-blocks") 33 #pragma GCC optimize("-fcse-follow-jumps") 34 #pragma GCC optimize("-fsched-interblock") 35 #pragma GCC optimize("-fpartial-inlining") 36 #pragma GCC optimize("no-stack-protector") 37 #pragma GCC optimize("-freorder-functions") 38 #pragma GCC optimize("-findirect-inlining") 39 #pragma GCC optimize("-fhoist-adjacent-loads") 40 #pragma GCC optimize("-frerun-cse-after-loop") 41 #pragma GCC optimize("inline-small-functions") 42 #pragma GCC optimize("-finline-small-functions") 43 #pragma GCC optimize("-ftree-switch-conversion") 44 #pragma GCC optimize("-foptimize-sibling-calls") 45 #pragma GCC optimize("-fexpensive-optimizations") 46 #pragma GCC optimize("-funsafe-loop-optimizations") 47 #pragma GCC optimize("inline-functions-called-once") 48 #pragma GCC optimize("-fdelete-null-pointer-checks") 49 # include <cstdio> 50 # include <iostream> 51 # include <cstring> 52 # include <algorithm> 53 # include <string> 54 # include <cmath> 55 # define mod 998244353 56 # define R register int 57 # define ll long long 58 59 using namespace std; 60 61 const int maxn=2004; 62 int n,k,h,x,y; 63 int firs[maxn],siz[maxn],dep[maxn]; 64 int dp[maxn][maxn]; 65 66 struct edge 67 { 68 int too,nex; 69 }g[maxn<<1]; 70 71 inline void add (int x,int y) 72 { 73 g[++h].too=y; 74 g[h].nex=firs[x]; 75 firs[x]=h; 76 } 77 78 inline int ad (int a,int b) 79 { 80 a+=b; 81 if(a>=mod) a-=mod; 82 return a; 83 } 84 85 void dfs (int x) 86 { 87 siz[x]=1; 88 int j; 89 dp[x][1]=1; 90 for (R i=firs[x];i;i=g[i].nex) 91 { 92 j=g[i].too; 93 if(dep[j]) continue; 94 dep[j]=dep[i]+1; 95 dfs(j); 96 siz[x]+=siz[j]; 97 for (R s=min(siz[x],k);s;--s) 98 { 99 if(s==1) 100 { 101 dp[x][s]=(1LL*dp[x][s]*dp[j][0])%mod; 102 continue; 103 } 104 dp[x][s]=(1LL*dp[x][s]*dp[j][0])%mod; 105 for (R f=1;f<=min(s,siz[j]);++f) 106 { 107 if(dp[x][s-f]==0||dp[j][f]==0) continue; 108 dp[x][s]=ad(dp[x][s],1LL*dp[x][s-f]*dp[j][f]%mod); 109 } 110 } 111 } 112 for (R i=1;i<=min(k,siz[x]);++i) 113 dp[x][0]=ad(dp[x][0],dp[x][i]); 114 } 115 116 inline char gc() 117 { 118 static char now[1<<22],*S,*T; 119 if (T==S) 120 { 121 T=(S=now)+fread(now,1,1<<22,stdin); 122 if (T==S) return EOF; 123 } 124 return *S++; 125 } 126 inline int read() 127 { 128 R x=0; 129 register char ch=gc(); 130 while(!isdigit(ch)) 131 ch=gc(); 132 while(isdigit(ch)) x=(x<<1)+(x<<3)+ch-‘0‘,ch=gc(); 133 return x; 134 } 135 136 int main() 137 { 138 n=read(),k=read(); 139 for (R i=1;i<n;++i) 140 { 141 x=read(),y=read(); 142 add(x,y); 143 add(y,x); 144 } 145 dep[1]=1; 146 dfs(1); 147 printf("%d",dp[1][0]); 148 return 0; 149 }藍魔法師
T4:http://www.nowcoder.com/acm/contest/215/D
題意概述:一個空的可重集合$S$,$n$次操作,每次操作給出$x,k,p$,執行以下操作:
1、在$S$中加入$x$。
2、輸出
所有數的範圍都是$1e5$
暴力(O(TLE)):
1 #pragma GCC diagnostic error "-std=c++14" 2 #pragma GCC target("avx") 3 #pragma GCC optimize(3) 4 #pragma GCC optimize("Ofast") 5 #pragma GCC optimize("inline") 6 #pragma GCC optimize("-fgcse") 7 #pragma GCC optimize("-fgcse-lm") 8 #pragma GCC optimize("-fipa-sra") 9 #pragma GCC optimize("-ftree-pre") 10 #pragma GCC optimize("-ftree-vrp") 11 #pragma GCC optimize("-fpeephole2") 12 #pragma GCC optimize("-ffast-math") 13 #pragma GCC optimize("-fsched-spec") 14 #pragma GCC optimize("unroll-loops") 15 #pragma GCC optimize("-falign-jumps") 16 #pragma GCC optimize("-falign-loops") 17 #pragma GCC optimize("-falign-labels") 18 #pragma GCC optimize("-fdevirtualize") 19 #pragma GCC optimize("-fcaller-saves") 20 #pragma GCC optimize("-fcrossjumping") 21 #pragma GCC optimize("-fthread-jumps") 22 #pragma GCC optimize("-funroll-loops") 23 #pragma GCC optimize("-fwhole-program") 24 #pragma GCC optimize("-freorder-blocks") 25 #pragma GCC optimize("-fschedule-insns") 26 #pragma GCC optimize("inline-functions") 27 #pragma GCC optimize("-ftree-tail-merge") 28 #pragma GCC optimize("-fschedule-insns2") 29 #pragma GCC optimize("-fstrict-aliasing") 30 #pragma GCC optimize("-fstrict-overflow") 31 #pragma GCC optimize("-falign-functions") 32 #pragma GCC optimize("-fcse-skip-blocks") 33 #pragma GCC optimize("-fcse-follow-jumps") 34 #pragma GCC optimize("-fsched-interblock") 35 #pragma GCC optimize("-fpartial-inlining") 36 #pragma GCC optimize("no-stack-protector") 37 #pragma GCC optimize("-freorder-functions") 38 #pragma GCC optimize("-findirect-inlining") 39 #pragma GCC optimize("-fhoist-adjacent-loads") 40 #pragma GCC optimize("-frerun-cse-after-loop") 41 #pragma GCC optimize("inline-small-functions") 42 #pragma GCC optimize("-finline-small-functions") 43 #pragma GCC optimize("-ftree-switch-conversion") 44 #pragma GCC optimize("-foptimize-sibling-calls") 45 #pragma GCC optimize("-fexpensive-optimizations") 46 #pragma GCC optimize("-funsafe-loop-optimizations") 47 #pragma GCC optimize("inline-functions-called-once") 48 #pragma GCC optimize("-fdelete-null-pointer-checks") 49 # include <cstdio> 50 # include <iostream> 51 # define R register int 52 53 using namespace std; 54 55 const int maxn=100005; 56 int n,x,k,p,a[maxn]; 57 int anss[maxn],vis[maxn],s,ans; 58 59 inline char gc() 60 { 61 static char now[1<<22],*S,*T; 62 if (T==S) 63 { 64 T=(S=now)+fread(now,1,1<<22,stdin); 65 if (T==S) return EOF; 66 } 67 return *S++; 68 } 69 inline int read() 70 { 71 R x=0; 72 register char ch=gc(); 73 while(!isdigit(ch)) 74 ch=gc(); 75 while(isdigit(ch)) x=(x<<1)+(x<<3)+ch-‘0‘,ch=gc(); 76 return x; 77 } 78 79 int gcd (int a,int b) 80 { 81 int p=1; 82 if(a<b) swap(a,b); 83 while(a&&b) 84 { 85 if(a%2==0&&b%2==0) p*=2,a/=2,b/=2; 86 else if(a%2&&b%2==0) b/=2; 87 else if(a%2==0&&b%2) a/=2; 88 else a-=b; 89 if(a<b) swap(a,b); 90 } 91 return p*a; 92 } 93 94 int qui (int a,int b) 95 { 96 int s=1; 97 while (b) 98 { 99 if(b&1) s=1LL*s*a%p; 100 a=1LL*a*a%p; 101 b=b>>1; 102 } 103 return s; 104 } 105 106 int main() 107 { 108 109 n=read(); 110 for (R i=1;i<=n;++i) 111 { 112 a[i]=read(); 113 k=read(); 114 p=read(); 115 ans=0; 116 for (R j=1;j<=i;++j) 117 { 118 if(vis[ a[j] ]==i) 119 s=anss[ a[j] ]; 120 else 121 { 122 int g=gcd(a[i],a[j]); 123 if(g==1) s=1; 124 else s=qui(g,k); 125 } 126 ans=ans+s; 127 if(ans>=p) ans-=p; 128 vis[ a[j] ]=i; 129 anss[ a[j] ]=s; 130 } 131 printf("%d\n",ans); 132 } 133 return 0; 134 }綠魔法師
T5:http://www.nowcoder.com/acm/contest/215/E
題意概述:對"灰魔法師"一題的延伸,要求構造一個長度為$n$的數列使得恰好有$k$對數相加是一個完全平方數.$n<=10^5,k<=10^{10}$
構造?等官方題解下來再說吧。
T6:http://www.nowcoder.com/acm/contest/215/F
題意概述:直接粘題面吧,$Wannafly$的題面都挺簡潔的.
一個空的二維平面上,每次加入或刪除一個整點。
求每次操作完之後滿足以下條件的三個點$p1,p2,p3$的對數。
1、$p1.y>p2.y>p3.y$;
2、$p1.x>max(p2.x,p3.x)$;
令操作數為n,保證$n<=60000,1<=x,y<=n$。
保證不會重復加入點,也不會刪除不存在的點;
這是啥...二維線段樹還是$CDQ$分治?順便問一下有沒有二維平衡樹啊.
所以我雖然沒做出來綠魔法師卻因此上綠名了?要是做出來豈不是可以黃名?
---shzr
Wannafly挑戰賽27