<style> .reveal .slides { text-align: left; font-size:35px } </style> # third week 2023 I2CP pretrain - MAT and Bitwise and perfix 2022/12/15 ---- 上週的解題狀況實在不甚理想,請有想要打比賽或是修課的同學多花一點時間在解題目上。 若是檢討到已經寫完的題目也可以聽聽看我們的解法,或者去寫其他題目。 同時,對於上週,希望大家寫掉的是 B , C , D , E , F , G ,I ---- ## pA 想法 $A_n = K * A_{n - 1} + L * A_{n - 2}$ $\begin{bmatrix} K&1\\L & 0 \\\end{bmatrix} * \begin{bmatrix} f[1] \\ f[0] \end{bmatrix}$ ---- ## pB 想法 sum = 0, f[1] = 1, f[0] = 0; $\begin{bmatrix} 1&1&0\\0 & 1 & 1 \\ 0 & 1 & 0 \\ \end{bmatrix} * \begin{bmatrix} sum \\ f[1] \\ f[0] \\ \end{bmatrix}$ ---- ## pC 想法 $\begin{bmatrix} 3&1\\1 & 3 \\\end{bmatrix} * \begin{bmatrix} 1 \\ 0\end{bmatrix}$ ---- ## pD 想法 最簡單的簽到題,只看測資感覺也會矇對的題目,基本上這題沒寫感覺是沒動腦。 使用性質:xor的運算 ```cpp= cout<<(x^y)<<"\n"; ``` ---- ## pE 想法 打比賽的要對小數字敏感一點,觀察它們可以幹嘛,像是這題的範圍會<230,那就直接對輸入進來的數字暴力打表就可以了。 每次做and紀錄答案 這題的話記憶體跟時間都沒有問題。 使用性質:and運算,打表處理 ---- ## 實作 ```cpp= #include<iostream> #include<cstring> using namespace std; int t,n,q,m,ans[230]={0}; int main(){ cin>>t; while(t--){ memset(ans,0,sizeof(ans)); //初始化 cin>>n>>q; while(n--){ cin>>m; for(int i=1;i<230;i++) //對範圍打表 ans[i]=max(ans[i],(i&m)); //按照題目要求 } while(q--) cin>>m,cout<<ans[m]<<"\n"; } } ``` ---- ## pF 想法 上課有講過,觀察規律,按照規律直接實作就會變成水題 (但這題蠻難的) 使用性質:觀察規律 ---- 實作 ```cpp= #include<iostream> using namespace std; long long a,b,now,cnt; int main(){ for(int t=1;true;t++){ cout<<"Case "<<t<<": "; cin>>a>>b; if(a==0&&b==0)break; a--,now=2,cnt=0; while(now<=1e13){ //到值域上限就好 long long aa=0,bb=0; aa+=a/now*(now/2); aa+=max(0LL,a-(a/now*now)-(now/2)+1); bb+=b/now*(now/2); bb+=max(0LL,b-(b/now*now)-(now/2)+1); cnt+=bb-aa; now<<=1; //每次檢查每個bit就好 } cout<<cnt<<endl; } } ``` ---- ## pG 想法 上課例題,會發現他就是前綴裸題問最大 使用性質:前綴和 ---- 實作核心代碼 ```cpp= for (int i = k + 1; i <= n; i++){ //k是長度限制 ans = max(ans, sum[i]-sum[i-k]); } cout<<ans<<"\n"; ``` ---- ## pH 想法 二維前綴和以及二維差分,問後面q次詢問的座標再前面m次是否包含在裡面 (若使用vector動態開點可以二維,若不是則只能降維) 使用性質:前綴和,差分 沒有要讓你們過la ---- ## pI 想法 先求出差分數組,然後再求出 $arr_1 ~ arr_n$的gcd(最大公因數) 使用性質:差分 ---- ```cpp= #include <iostream> #include<algorithm> using namespace std; int main() { int x; while (cin >> x && x){ int a[1005]; int N = 1; a[0] = x; while (cin >> x && x) a[N++] = x; int d = abs(a[0] - a[1]); for (int i = 1; i < N-1; i++){ d = __gcd(d, abs(a[i] - a[i+1])); } cout << d << "\n"; } return 0; } ``` ---- ## pJ 想法 先求出差分數組,然後可以檢視三個操作分別會對差分數組造成甚麼影響 使用性質:差分 ---- ```cpp= int main(){ int t,n; cin>>t; while(t--){ cin>>n; int all[n]; int f[n]; for(int i=0;i<n;i++){ cin>>all[i]; if(i>0)f[i]=all[i]-all[i-1]; } f[0]=all[0]; int ans=0; for(int i=1;i<n;i++){ ans+=abs(f[i]); if(f[i]<0)f[0]+=f[i]; } ans+=abs(f[0]); cout<<ans<<endl; } } ```
{"metaMigratedAt":"2023-06-17T16:39:42.002Z","metaMigratedFrom":"YAML","title":"third week","breaks":true,"contributors":"[{\"id\":\"19f09ccf-6b99-452f-971f-955cfc1657f3\",\"add\":1,\"del\":1},{\"id\":\"e4a3af8b-860c-46a0-96f1-558667fdcf41\",\"add\":3796,\"del\":576}]"}
    290 views
   Owned this note