Educational Codeforces Round 71 (Rated for Div. 2)
Posted HinanawiTenshi
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Educational Codeforces Round 71 (Rated for Div. 2)相关的知识,希望对你有一定的参考价值。
传送门: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;
}
以上是关于Educational Codeforces Round 71 (Rated for Div. 2)的主要内容,如果未能解决你的问题,请参考以下文章
Educational Codeforces Round 7 A
Educational Codeforces Round 7
Educational Codeforces Round 90
Educational Codeforces Round 33