小去世:我正在看着視頻吃着飯,突然隊群里來了句:“zwt大人起床了嗎。”
賽前直接被迫犯罪。
先說一下總體體驗:非常差。
看了各方言論,感覺也不能把鍋直接甩給HDOJ,東部樞紐罪不至此。但是寫題半小時提交半小時查記錄半小時體驗實在實在是太差了。
隊里寫完AFI三道簽到題其實優勢很大,可惜自己拉了跨。
A - Cut The Wire
簽中簽,可惜手慢20+分鍾才核對完submit還被網站惡心()。奇數答案\((n-1)/3 \leq x \leq n\),偶數答案\((n+1) \leq x \leq 2n\),記得細節處理兩端奇偶即可。
#include<bits/stdc++.h> #define fast ios::sync_with_stdio(0),cin.tie(0),cout.tie(0) #define ll long long #define pb push_back using namespace std; const int maxn = 1e5+10; int main() { fast; int T; cin>>T; while(T--) { ll n; cin>>n; ll tmp1=(n-1)/3; tmp1++; ll sum1=(n-tmp1),sum2=(n-1); sum2=sum2/2; sum2++; if(tmp1%2+n%2==0) sum1=sum1/2; else sum1=sum1/2+1; //cout<<sum1<<' '<<sum2<<'\n'; cout<<sum1+sum2<<'\n'; } }
I - Command Sequence
隊友開的題,簡單地說一下,利用map分別記錄每個點經過的次數\(x\),每個點的次數所帶來的貢獻為\(x*(x-1)/2\)。
F - Power Sum
當時看到平方數就想到去要做差,這樣可以穩定湊到一個4,隨后就是湊得模4后的余數。\(1=1\),\(2=1-4-9+16\),\(3=-1+4\) ,這樣就可以湊得我想要的任意一個數,且保證\(k \leq n+2\)。
#include<bits/stdc++.h> #define fast ios::sync_with_stdio(0),cin.tie(0),cout.tie(0) #define ll long long #define pb push_back using namespace std; const int maxn = 1e5+10; int main() { fast; int T; cin>>T; int cnt=0; while(T--) { cnt=0; int n; cin>>n; if(n%4==0) cout<<n<<'\n'; if(n%4==1) cout<<n<<'\n',cout<<"1",n-=1; if(n%4==2) cout<<n+2<<'\n',cout<<"0001",n-=2; if(n%4==3) cout<<n-1<<'\n',cout<<"01",n-=3; for(int i=1;i<=n/4;i++) { cout<<"1001"; } cout<<'\n'; } }
G - Function
我連參與都沒參與,我是菜狗,隊友真強。
L - Remove
一直WA,最后發現自己思路是錯的。
原本想的是,記最大質數為\(x\),以\(x \leq i \leq 2*x-1\)這個區間為例,對於每一個不是最大質數的每一個質數,找到\(p[j]-2*x \% p[j]\)的最大值(余數為0視為余數為\(p[j]\)),在這個最大值前的部分答案等於\(x\)時的答案,后面部分\(+1\),每次遇到最大質數的倍數無條件\(+1\)。
小去世:昨天寫完上面那個公式沒仔細看,Latex寫爛了。(其實是根本不會Latex)
思路完全來自於官方題解,並且T了,遺憾離場,先放着吧。
\(i \geq lcm(P)\)時無解,這個很顯然,沒有辦法從最小公倍數往下走了。
在有解的情況下,答案非遞減,這個算兩個也能發現。(而且上面的思路也很明顯地發現是非遞減的)
對於任意一個\(x\),存在一個因子\(p\),則它的轉移區間為\([x+1,x+p-1]\),那么我的最優選擇是找到最大的因子。
由於給的都是素數,所以寫了個像埃篩的東西標記每個數的最大素因子。
接下來是求助時間:
#include<bits/stdc++.h> #define fast ios::sync_with_stdio(0),cin.tie(0),cout.tie(0) #define ll long long #define pb push_back using namespace std; const int maxn = 2e6+10; const int maxm = 1e5+10; ll a[maxn]; ll p[maxm]; ll f[maxn]; ll maxx=0; ll Lcm; ll n,m; __int128 cur[maxn]; const __int128 mod = pow(2,64); void init1() { cur[0]=1; for(int i=1;i<=2e6;i++) { cur[i]=cur[i-1]*23333%mod; } } void init2(ll x) { for(int i=1;i<=m;i++) { f[p[i]]=p[i]; } for(int i=1;i<=m;i++) { for(int j=p[i];j<x;j+=p[i]) { f[j]=max(f[j],p[i]); } } } void Print(__int128 x) { if (x < 0) cout<<'-', x = -x; if (x > 9) Print(x / 10); cout<<(char)(x%10+48); } void print(ll x) { __int128 ans=0; for(int i=1;i<=x;i++) { ans=(ans+a[i]*cur[x-i])%mod; } Print(ans); cout<<'\n'; } int main() { fast; init1(); int T; cin>>T; while(T--) { Lcm=1; int flag=1; maxx=0; cin>>n>>m; for(int i=1;i<=n;i++) { f[i]=1; a[i]=1e9; } for(int i=1;i<=m;i++) { cin>>p[i]; maxx=max(maxx,p[i]); if(flag) { Lcm*=p[i]; if(Lcm>n) { Lcm=n+1; flag=0; } } } init2(Lcm); for(int i=1;i<maxx;i++) { a[i]=1; } for(int i=1;i<Lcm;i++) { if(f[i]==1) continue; for(int j=i+1;j<=min(Lcm-1,i+f[i]-1);j++) { //cout<<i<<' '<<j<<'\n'; a[j]=min(a[j],a[i]+1); } } for(int i=Lcm;i<=n;i++) a[i]=0; print(n); // for(int i=1;i<=n;i++) // { // cout<<a[i]<<" "; // } // cout<<'\n'; } }
不知道有什么優化的點,咣咣咣給爹們磕頭了。