今天早上開的一把\(\rm vp\),前四題很水,看了\(\rm E,F\)以後我去寫了\(\rm F\),而後還沒調出來血虧...賽後才發現\(\rm E\)是真的水...c++
比賽傳送門:https://codeforces.com/contest/1151git
https://codeforces.com/contest/1151/problem/A優化
直接暴力就行了。spa
#include<bits/stdc++.h> using namespace std; #define int long long void read(int &x) { x=0;int f=1;char ch=getchar(); for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-f; for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';x*=f; } void print(int x) { if(x<0) putchar('-'),x=-x; if(!x) return ;print(x/10),putchar(x%10+48); } void write(int x) {if(!x) putchar('0');else print(x);putchar('\n');} #define lf long double #define ll long long #define pii pair<int,int > #define vec vector<int > #define pb push_back #define mp make_pair #define fr first #define sc second #define FOR(i,l,r) for(int i=l,i##_r=r;i<=i##_r;i++) const int maxn = 2e5+10; const int inf = 1e9; const lf eps = 1e-12; const int mod = 1e9+7; int n; char s[maxn]; int get(int a,int b) { return min(abs(a-b),26-max(a,b)+min(a,b)); } signed main() { read(n);scanf("%s",s+1); int ans=1e9; for(int i=1;i<=n-3;i++) ans=min(ans,get(s[i],'A')+get(s[i+1],'C')+get(s[i+2],'T')+get(s[i+3],'G')); write(ans); return 0; }
https://codeforces.com/contest/1151/problem/Bcode
這題很奇怪...我只會亂搞...component
咱們考慮每一列隨機一個數出來,隨機一萬次,錯誤的機率趨近於\(0\)了。orm
#include<bits/stdc++.h> using namespace std; #define int long long void read(int &x) { x=0;int f=1;char ch=getchar(); for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-f; for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';x*=f; } void print(int x) { if(x<0) putchar('-'),x=-x; if(!x) return ;print(x/10),putchar(x%10+48); } void write(int x) {if(!x) putchar('0');else print(x);putchar('\n');} #define lf long double #define ll long long #define pii pair<int,int > #define vec vector<int > #define pb push_back #define mp make_pair #define fr first #define sc second #define FOR(i,l,r) for(int i=l,i##_r=r;i<=i##_r;i++) const int maxn = 2e5+10; const int inf = 1e9; const lf eps = 1e-12; const int mod = 998244353; const int inv2 = 499122177; int n,m,a[505][505],t[505]; signed main() { srand(time(0)); read(n),read(m);FOR(i,1,n) FOR(j,1,m) read(a[i][j]); for(int i=1;i<=20000;i++) { int res=0; for(int j=1;j<=n;j++) res^=a[j][t[j]=rand()%m+1]; if(res) { puts("TAK"); for(int k=1;k<=n;k++) printf("%d ",t[k]); puts("");return 0; } }puts("NIE"); return 0; }
https://codeforces.com/contest/1151/problem/C排序
倍增,而後按題意模擬。get
#include<bits/stdc++.h> using namespace std; #define int long long void read(int &x) { x=0;int f=1;char ch=getchar(); for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-f; for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';x*=f; } void print(int x) { if(x<0) putchar('-'),x=-x; if(!x) return ;print(x/10),putchar(x%10+48); } void write(int x) {if(!x) putchar('0');else print(x);putchar('\n');} #define lf long double #define ll long long #define pii pair<int,int > #define vec vector<int > #define pb push_back #define mp make_pair #define fr first #define sc second #define FOR(i,l,r) for(int i=l,i##_r=r;i<=i##_r;i++) const int maxn = 2e5+10; const int inf = 1e9; const lf eps = 1e-12; const int mod = 1e9+7; const int inv2 = 5e8+4; int a[2]; int sum(int x,int y,int t) { int qwe=(y-x+1)%mod; x<<=1,y<<=1;if(t) x--,y--; x%=mod,y%=mod; return 1ll*(x+y)*qwe%mod*inv2%mod; } int solve(int r) { int tot=0,now=1,kd=1; int ans=0;a[0]=a[1]=1; while(tot<r) { if(tot+now>r) ans+=sum(a[kd],a[kd]+r-now,kd); else ans+=sum(a[kd],a[kd]+now-1,kd); a[kd]+=now,tot+=now,now<<=1,kd^=1; }return (ans%mod+mod)%mod; } signed main() { int l,r;read(l),read(r); write((solve(r)-solve(l-1)+mod)%mod); return 0; }
https://codeforces.com/contest/1151/problem/Dit
把式子拆開就是:
\[ nb_i-a_i+j\cdot (a_i-b_i) \]
因此直接貪心的按\(a_i-b_i\)排序就行了。
#include<bits/stdc++.h> using namespace std; #define int long long void read(int &x) { x=0;int f=1;char ch=getchar(); for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-f; for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';x*=f; } void print(int x) { if(x<0) putchar('-'),x=-x; if(!x) return ;print(x/10),putchar(x%10+48); } void write(int x) {if(!x) putchar('0');else print(x);putchar('\n');} #define lf long double #define ll long long #define pii pair<int,int > #define vec vector<int > #define pb push_back #define mp make_pair #define fr first #define sc second #define FOR(i,l,r) for(int i=l,i##_r=r;i<=i##_r;i++) const int maxn = 2e5+10; const int inf = 1e9; const lf eps = 1e-12; const int mod = 998244353; const int inv2 = 499122177; int n,a[maxn],b[maxn],t[maxn]; signed main() { read(n);FOR(i,1,n) read(a[i]),read(b[i]),t[i]=a[i]-b[i]; sort(t+1,t+n+1);int res=0; for(int i=n;i;i--) res+=t[n-i+1]*i; for(int i=1;i<=n;i++) res+=-1*a[i]+n*b[i]; write(res); return 0; }
https://codeforces.com/contest/1151/problem/E
注意到森林的連通塊個數\(=\)點數\(-\)邊數。
枚舉每一個點和每條邊的貢獻就行。
#include<bits/stdc++.h> using namespace std; #define int long long void read(int &x) { x=0;int f=1;char ch=getchar(); for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-f; for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';x*=f; } #define ll long long void print(ll x) { if(x<0) putchar('-'),x=-x; if(!x) return ;print(x/10),putchar(x%10+48); } void write(ll x) {if(!x) putchar('0');else print(x);putchar('\n');} #define lf double #define pii pair<int,int > #define vec vector<int > #define pb push_back #define mp make_pair #define fr first #define sc second #define FOR(i,l,r) for(int i=l,i##_r=r;i<=i##_r;i++) const int maxn = 2e5+10; const int inf = 1e9; const lf eps = 1e-8; ll ans,s; int n,a[maxn]; int c(int x) {return x*(x-1)/2+x;} signed main() { read(n);FOR(i,1,n) read(a[i]),ans+=c(n)-c(n-a[i])-c(a[i]-1); FOR(i,1,n-1) { int l=min(a[i],a[i+1]),r=max(a[i],a[i+1]); ans-=1ll*l*(n-r+1); }write(ans); return 0; }
https://codeforces.com/contest/1151/problem/F
這是這場惟一有點難度的題了...多是我太菜了吧
注意到最終狀態必定是前面\(k\)個\(0\),後面全是\(1\),其中\(k\)爲一開始\(0\)的個數。
咱們考慮一個暴力的\(dp\),設\(f[i][j]\)表示進行了\(i\)次操做,前\(k\)個位置有\(j\)個\(0\)的狀況總數。
而後轉移枚舉幾種狀況:
這樣轉移複雜度爲\(O(nk)\),可是\(k\)太大了過不了。
注意到\(n\)只有\(100\)咱們能夠用矩陣優化上面的轉移,複雜度\(O(n^3\log k)\)。
#include<bits/stdc++.h> using namespace std; #define int long long void read(int &x) { x=0;int f=1;char ch=getchar(); for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-f; for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';x*=f; } void print(int x) { if(x<0) putchar('-'),x=-x; if(!x) return ;print(x/10),putchar(x%10+48); } void write(int x) {if(!x) putchar('0');else print(x);putchar('\n');} #define lf long double #define ll long long #define pii pair<int,int > #define vec vector<int > #define pb push_back #define mp make_pair #define fr first #define sc second #define FOR(i,l,r) for(int i=l,i##_r=r;i<=i##_r;i++) const int maxn = 2e5+10; const int inf = 1e9; const lf eps = 1e-12; const int mod = 1e9+7; int add(int x,int y) {return x+y>=mod?x+y-mod:x+y;} int del(int x,int y) {return x-y<0?x-y+mod:x-y;} int mul(int x,int y) {return 1ll*x*y-1ll*x*y/mod*mod;} void inc(int &x,int y) {x+=y;x%=mod;} int n,k,a[maxn],res,c; int qpow(int a,int x) { int res=1; for(;x;x>>=1,a=1ll*a*a%mod) if(x&1) res=1ll*res*a%mod; return res; } struct Matrix { int a,b,r[110][110]; Matrix () {a=b=0,memset(r,0,sizeof r);} Matrix operator * (const Matrix &t) const { Matrix res;res.a=a,res.b=t.b; for(int i=0;i<=a;i++) for(int j=0;j<=t.b;j++) for(int k=0;k<=b;k++) res.r[i][j]=add(res.r[i][j],mul(r[i][k],t.r[k][j])); return res; } }tr,ans; signed main() { read(n),read(k); for(int i=1;i<=n;i++) read(a[i]),res+=!(a[i]&1); for(int i=1;i<=res;i++) c+=!a[i]; ans.a=0,ans.b=res;ans.r[0][c]=1;tr.a=tr.b=res; for(int i=0;i<=res;i++) { int lw=i,lb=res-i,rw=res-lw,rb=n-res-lb; if(i!=res) inc(tr.r[i][i+1],lb*rw%mod); if(i!=0) inc(tr.r[i][i-1],lw*rb%mod); inc(tr.r[i][i],(res*(res-1)+(n-res)*(n-res-1))%mod*qpow(2,mod-2)%mod); inc(tr.r[i][i],(lw*lb+rw*rb)%mod); } int x=k,f=0; for(;x;x>>=1,tr=tr*tr) if(x&1) ans=ans*tr; FOR(i,0,res) f=(f+ans.r[0][i])%mod;write(ans.r[0][res]*qpow(f,mod-2)%mod); return 0; }