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\\) 次询问做出对应的两个操作:

  1. 将下标为 \\(x\\) 的位置的值加上 \\(y\\)
  2. 询问所有下标模 \\(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

Codeforces Educational Codeforces Round 54 题解

Educational Codeforces Round 27