Educational Codeforces Round 71 (Rated for Div. 2)
阿新 • • 發佈:2021-06-22
傳送門:https://codeforces.com/contest/1207
A
模擬
#pragma GCC optimize("O3") #include<bits/stdc++.h> using namespace std; #define endl '\n' #define debug(x) cerr << #x << ": " << x << endl #define pb(a) push_back(a) #define set0(a) memset(a,0,sizeof(a)) #define rep(i,a,b) for(int i=(a);i<=(b);i++) #define dwn(i,a,b) for(int i=(a);i>=(b);i--) #define ceil(a,b) (a+(b-1))/b #define INF 0x3f3f3f3f #define ll_INF 0x7f7f7f7f7f7f7f7f typedef long long ll; typedef pair<int,int> PII; typedef pair<double,double> PDD; inline void read(int &x) { int s=0;x=1; char ch=getchar(); while(ch<'0'||ch>'9') {if(ch=='-')x=-1;ch=getchar();} while(ch>='0'&&ch<='9') s=(s<<3)+(s<<1)+ch-'0',ch=getchar(); x*=s; } int main(){ int T; cin>>T; while(T--){ int a, b, c; cin>>a>>b>>c; int u, v; cin>>u>>v; int res=0; while(a>=2 && (b || c)){ if(u>v){ if(b) b--, res+=u; else c--, res+=v; } else{ if(c) c--, res+=v; else b--, res+=u; } a-=2; } cout<<res<<endl; } return 0; }
B
如果說一個格子需要改為 \(1\) ,那麼就看看他周圍四個方向能不能做出相應操作,如果能就操作。如果都不能就是無解。
#pragma GCC optimize("O3") #include<bits/stdc++.h> using namespace std; #define endl '\n' #define debug(x) cerr << #x << ": " << x << endl #define pb(a) push_back(a) #define set0(a) memset(a,0,sizeof(a)) #define rep(i,a,b) for(int i=(a);i<=(b);i++) #define dwn(i,a,b) for(int i=(a);i>=(b);i--) #define ceil(a,b) (a+(b-1))/b #define INF 0x3f3f3f3f #define ll_INF 0x7f7f7f7f7f7f7f7f typedef long long ll; typedef pair<int,int> PII; typedef pair<double,double> PDD; inline void read(int &x) { int s=0;x=1; char ch=getchar(); while(ch<'0'||ch>'9') {if(ch=='-')x=-1;ch=getchar();} while(ch>='0'&&ch<='9') s=(s<<3)+(s<<1)+ch-'0',ch=getchar(); x*=s; } const int N=55; int g[N][N]; set<PII> res; int main(){ int n, m; cin>>n>>m; rep(i,1,n) rep(j,1,m) read(g[i][j]); bool ok=true; rep(i,1,n) rep(j,1,m) if(g[i][j]){ bool flag=false; if(g[i-1][j-1] && g[i-1][j] && g[i][j-1]) res.insert({i-1, j-1}), flag=true; if(g[i-1][j] && g[i-1][j+1] && g[i][j+1]) res.insert({i-1, j}), flag=true; if(g[i][j+1] && g[i+1][j] && g[i+1][j+1]) res.insert({i, j}), flag=true; if(g[i][j-1] && g[i+1][j-1] && g[i+1][j]) res.insert({i, j-1}), flag=true; if(!flag) ok=false; } if(!ok){ puts("-1"); return 0; } cout<<res.size()<<endl; for(auto i: res) cout<<i.first<<' '<<i.second<<endl; return 0; }
C
貪心
#pragma GCC optimize("O3") #include<bits/stdc++.h> using namespace std; #define endl '\n' #define debug(x) cerr << #x << ": " << x << endl #define pb(a) push_back(a) #define set0(a) memset(a,0,sizeof(a)) #define rep(i,a,b) for(int i=(a);i<=(b);i++) #define dwn(i,a,b) for(int i=(a);i>=(b);i--) #define ceil(a,b) (a+(b-1))/b #define INF 0x3f3f3f3f #define ll_INF 0x7f7f7f7f7f7f7f7f typedef long long ll; typedef pair<int,int> PII; typedef pair<double,double> PDD; #define int long long inline void read(int &x) { int s=0;x=1; char ch=getchar(); while(ch<'0'||ch>'9') {if(ch=='-')x=-1;ch=getchar();} while(ch>='0'&&ch<='9') s=(s<<3)+(s<<1)+ch-'0',ch=getchar(); x*=s; } const int N=2e5+5; int stk[N],tot; signed main(){ int T; cin>>T; while(T--){ tot=0; int n, a, b; read(n), read(a), read(b); string s; cin>>s; s=' '+s; int res=n*(a+b)+b; int i=1; while(i<=n){ int cnt=0; while(s[i]=='0' && i<=n) cnt++, i++; stk[++tot]=cnt, cnt=0; if(s[i]=='1'){ while(s[i]=='1' && i<=n) cnt++, i++; stk[++tot]=cnt; } } if(tot==1){ // cerr<<"imsb"; cout<<res<<endl; continue; } // rep(i,1,tot) debug(stk[i]); // debug(tot); debug(res); res+=a; for(int i=2; i<tot; i+=2){ res+=stk[i]*b+b; if(i==tot-1){ res+=a; continue; } // debug(min(2*a, (stk[i+1]-1)*b)); res+=min(2*a, (stk[i+1]-1)*b); // debug(res); } cout<<res<<endl; } return 0; }
D
利用容斥原理進行統計。
我們將 \(bad\) 的序列分為三類:分別記為 \(bad_1,bad_2,bad_{1∩2}\)
\(good = all - (bad_1 + bad_2 - bad_{1∩2})\)
#pragma GCC optimize("O3")
#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
#define debug(x) cerr << #x << ": " << x << endl
#define pb(a) push_back(a)
#define set0(a) memset(a,0,sizeof(a))
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define dwn(i,a,b) for(int i=(a);i>=(b);i--)
#define ceil(a,b) (a+(b-1))/b
#define INF 0x3f3f3f3f
#define ll_INF 0x7f7f7f7f7f7f7f7f
typedef long long ll;
typedef pair<double,double> PDD;
#define int long long
typedef pair<int,int> PII;
#define x first
#define y second
inline void read(int &x) {
int s=0;x=1;
char ch=getchar();
while(ch<'0'||ch>'9') {if(ch=='-')x=-1;ch=getchar();}
while(ch>='0'&&ch<='9') s=(s<<3)+(s<<1)+ch-'0',ch=getchar();
x*=s;
}
const int N=3e5+5, mod=998244353;
int fac[N];
void init(){
fac[0]=fac[1]=1;
rep(i,2,N-1) fac[i]=fac[i-1]*i%mod;
}
PII q[N];
int n;
int res[4];
bool cmp(PII u, PII v){
return u.y<v.y;
// else return u.x<v.x;
}
signed main(){
init();
read(n);
rep(i,1,n) read(q[i].x), read(q[i].y);
sort(q+1, q+1+n);
int t=1;
rep(i,1,n-1){
if(q[i].x!=q[i+1].x) continue;
int cnt=1;
while(q[i].x==q[i+1].x) cnt++, i++;
t=(t*fac[cnt])%mod;
}
res[1]=t;
t=1;
sort(q+1, q+1+n, cmp);
rep(i,1,n-1){
if(q[i].y!=q[i+1].y) continue;
int cnt=1;
while(q[i].y==q[i+1].y) cnt++, i++;
t=(t*fac[cnt])%mod;
}
res[2]=t;
t=1;
sort(q+1, q+1+n);
bool fl=true;
rep(i,1,n-1) if(q[i].y>q[i+1].y) fl=false;
rep(i,1,n-1){
if(q[i].x!=q[i+1].x) continue;
int cnt=1;
while(q[i].x==q[i+1].x && q[i].y==q[i+1].y) cnt++, i++;
t=(t*fac[cnt])%mod;
}
if(fl) res[3]=t;
// rep(i,1,3) debug(res[i]);
int ans=((fac[n]-(res[1]+res[2]-res[3]))%mod+mod)%mod;
cout<<ans<<endl;
return 0;
}
E
第一次詢問將末 \(7\) 位全部填充為 \(1\) 得到答案末 \(7\) 位,第二次詢問將首 \(7\) 位全部填充為 \(1\) 得到答案首 \(7\) 位。
#pragma GCC optimize("O3")
#include<bits/stdc++.h>
using namespace std;
// #define endl '\n'
#define debug(x) cerr << #x << ": " << x << endl
#define pb(a) push_back(a)
#define set0(a) memset(a,0,sizeof(a))
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define dwn(i,a,b) for(int i=(a);i>=(b);i--)
#define ceil(a,b) (a+(b-1))/b
#define INF 0x3f3f3f3f
#define ll_INF 0x7f7f7f7f7f7f7f7f
typedef long long ll;
typedef pair<int,int> PII;
typedef pair<double,double> PDD;
#define int long long
inline void read(int &x) {
int s=0;x=1;
char ch=getchar();
while(ch<'0'||ch>'9') {if(ch=='-')x=-1;ch=getchar();}
while(ch>='0'&&ch<='9') s=(s<<3)+(s<<1)+ch-'0',ch=getchar();
x*=s;
}
int q[105];
signed main(){
int t;
t=127;
rep(i,1,100) q[i]=128*i+t;
cout<<"? ";
rep(i,1,100) cout<<q[i]<<' ';
cout<<endl;
int num; cin>>num;
num^=t;
string res1;
dwn(i,6,0) res1+= num>>i&1? '1': '0';
t*=128;
rep(i,1,100) q[i]=i+t;
cout<<"? ";
rep(i,1,100) cout<<q[i]<<' ';
cout<<endl;
cin>>num;
num^=t;
string res2;
dwn(i,13,7) res2+= num>>i&1? '1': '0';
bitset<20> bs(res2+res1);
cout<<"! "<<bs.to_ulong()<<endl;
return 0;
}
F
題目大意
給出一個初始值全部為 \(0\) 的,從 \(1\) 開始編號,長度為 \(500000\) 的序列,要求對 \(q\) 次詢問做出對應的兩個操作:
- 將下標為 \(x\) 的位置的值加上 \(y\)
- 詢問所有下標模 \(x\) 的結果為 \(y\) 的位置的值之和
分析
拿到題目,發現沒有什麼現成的資料結構可以維護這兩個操作,根據經驗,我們可以考慮優雅的暴力——分塊。
不妨將操作 \(2\) 形象地解釋為將序列中初相位為 \(y\) ,週期為 \(x\) 的下標對應的數求和。
那麼思路是:
-
當塊長較大時,我們暴力地統計答案,也就是直接列舉進行統計。
-
而當塊長較小時,將答案存在
ans[T][phi]
中,並進行維護。
這裡的 \(T\) 意思是週期,而 \(phi\) (也就是 \(\phi\))指的是初相位。
細節見程式碼(很短的 \(awa\))
#pragma GCC optimize("O3")
#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define dwn(i,a,b) for(int i=(a);i>=(b);i--)
#define int long long
inline void read(int &x) {
int s=0;x=1;
char ch=getchar();
while(ch<'0'||ch>'9') {if(ch=='-')x=-1;ch=getchar();}
while(ch>='0'&&ch<='9') s=(s<<3)+(s<<1)+ch-'0',ch=getchar();
x*=s;
}
const int N=5e5+5, L=707;
int w[N], q;
int ans[L+5][L+5]; // 第一維代表週期,第二維代表初相位,值代表對應的和
signed main(){
read(q);
while(q--){
int op, x, y; read(op), read(x), read(y);
if(op&1){
w[x]+=y;
rep(i,1,L) ans[i][x%i]+=y;
}
else{
if(x<=L) cout<<ans[x][y]<<endl;
else{
int t=0;
for(int i=y; i<=N; i+=x) t+=w[i];
cout<<t<<endl;
}
}
}
return 0;
}