第二天打卡 (昨天cf炸了,寫到一半上不去了,今天重新開一套寫,晚上會補上今天改寫的第三套)Educational Codeforces Round 72 (Rated for Div. 2)


題目出的挺好的,數學知識較多。虛擬rk:801
A.Creating a Character
題意:給出力量和敏捷兩個屬性,現在給出技能點數,在必須使用完技能點數的情況下,有多少種情況,力量屬性嚴格大於敏捷。
wa了4次。
細節蠻多的。可以推導出來 (力量-敏捷)+技能點數/2>點在敏捷上的技能點數 就能滿足題意。
不過需要特判,敏捷額外的點數不能超過所有技能點數,而且不能為負數。

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<climits>
#include<stack>
#include<vector>
#include<queue>
#include<set>
#include<bitset>
#include<map>
//#include<regex>
#include<cstdio>
#define up(i,a,b)  for(int i=a;i<b;i++)
#define dw(i,a,b)  for(int i=a;i>b;i--)
#define upd(i,a,b) for(int i=a;i<=b;i++)
#define dwd(i,a,b) for(int i=a;i>=b;i--)
//#define local
typedef long long ll;
typedef unsigned long long ull;
const double esp = 1e-6;
const double pi = acos(-1.0);
const int INF = 0x3f3f3f3f;
const int inf = 1e9;
using namespace std;
ll read()
{
	char ch = getchar(); ll x = 0, f = 1;
	while (ch<'0' || ch>'9') { if (ch == '-')f = -1; ch = getchar(); }
	while (ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); }
	return x * f;
}
typedef pair<int, int> pir;
#define lson l,mid,root<<1
#define rson mid+1,r,root<<1|1
#define lrt root<<1
#define rrt root<<1|1
int T;
ll a, b, c;
int main()
{
	T = read();
	while (T--)
	{
		a = read();
		b = read();
		c = read();
		if (c == 0)printf("%d\n", a>b?1:0);
		else {
			ll temp = a - b;
			if ((temp + c) <= 0)printf("%d\n", 0);
			else {
				if (temp > c)printf("%d\n", c+1);
				else {
					ll tmepy = (temp + c) / 2;
					if ((temp + c) % 2)tmepy++;
					printf("%d\n", tmepy);
				}
			}
		}
	}
	return 0;
}

B - Zmei Gorynich
題意:龍有n個頭,現在有幾種攻擊可以選擇,砍掉di個頭,然后龍長出hi個頭。
同樣是細節數學題目。

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<climits>
#include<stack>
#include<vector>
#include<queue>
#include<set>
#include<bitset>
#include<map>
//#include<regex>
#include<cstdio>
#define up(i,a,b)  for(int i=a;i<b;i++)
#define dw(i,a,b)  for(int i=a;i>b;i--)
#define upd(i,a,b) for(int i=a;i<=b;i++)
#define dwd(i,a,b) for(int i=a;i>=b;i--)
//#define local
typedef long long ll;
typedef unsigned long long ull;
const double esp = 1e-6;
const double pi = acos(-1.0);
const int INF = 0x3f3f3f3f;
const int inf = 1e9;
using namespace std;
ll read()
{
	char ch = getchar(); ll x = 0, f = 1;
	while (ch<'0' || ch>'9') { if (ch == '-')f = -1; ch = getchar(); }
	while (ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); }
	return x * f;
}
typedef pair<int, int> pir;
#define lson l,mid,root<<1
#define rson mid+1,r,root<<1|1
#define lrt root<<1
#define rrt root<<1|1
int t;
int n, x;
struct node {
	int d, h, dis;
}tr[1000];
int main()
{
	t = read();
	while (t--)
	{
		n = read();
		x = read();
		int maxn1 = -1;
		int pos1 = -1;
		int maxn2 = -1;
		int pos2 = -1;
		up(i, 0, n)
		{
			tr[i].d = read();
			tr[i].h = read();
			tr[i].dis = tr[i].d - tr[i].h;
			if (maxn1 < tr[i].d)
			{
				maxn1 = tr[i].d;
				pos1 = i;
			}
			if (maxn2 < tr[i].dis)
			{
				maxn2 = tr[i].dis;
				pos2 = i;
			}
		}
		if (maxn1 >= x) { printf("%d\n", 1); }
		else
		{
			int ans = 0;
			if (maxn2 <= 0) { printf("%d\n", -1); continue; }
			if ((x - maxn1) % maxn2 == 0)ans = (x - maxn1) / maxn2;
			else ans = (x - maxn1) / maxn2 + 1;
			printf("%d\n",++ans );
		}
	}
}

c. 題意:給一個01字符串,求他的字串的二進制等於字串長度的所有情況。
由題意,長度最長為2e5,二進制長度最長20。意思就是說,如果當前為1,那么他往后最長為20。
其次我們需要考慮前導零。加上前導零的影響,我們暴力判斷就好了。

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<climits>
#include<stack>
#include<vector>
#include<queue>
#include<set>
#include<bitset>
#include<map>
//#include<regex>
#include<cstdio>
#define up(i,a,b)  for(int i=a;i<b;i++)
#define dw(i,a,b)  for(int i=a;i>b;i--)
#define upd(i,a,b) for(int i=a;i<=b;i++)
#define dwd(i,a,b) for(int i=a;i>=b;i--)
//#define local
typedef long long ll;
typedef unsigned long long ull;
const double esp = 1e-6;
const double pi = acos(-1.0);
const int INF = 0x3f3f3f3f;
const int inf = 1e9;
using namespace std;
ll read()
{
	char ch = getchar(); ll x = 0, f = 1;
	while (ch<'0' || ch>'9') { if (ch == '-')f = -1; ch = getchar(); }
	while (ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); }
	return x * f;
}
typedef pair<int, int> pir;
#define lson l,mid,root<<1
#define rson mid+1,r,root<<1|1
#define lrt root<<1
#define rrt root<<1|1
int t;
const int N = 2e5 + 10;
char s[N];
int main()
{
	t = read();
	while (t--) {
 
		scanf("%s", s);
		int n = strlen(s);
		int num_0 = 0;
		int ans = 0;
		up(i, 0, n)
		{
			if (s[i] == '0') {
				num_0++; continue;
			}
			int temp = 0;
			int cnt = 1;
			up(j, i, n) {
				temp<<=1;
				temp |= s[j] == '1' ? 1 : 0;
				if (temp <= num_0 + j - i + 1)ans++;
				if(j!=i)
				cnt <<= 1;
				if (cnt > (int)2e5 + 1)break;
			}
			num_0 = 0;
		}
		cout << ans << endl;
	}
}

D:
確實沒想到。。推出了只有1,2兩種情況,然后想的是交替染色,然而代碼寫崩了。。
題意:給圖染色,唯一的條件就是這個圖里面的環不能只有一種顏色。
我們由scc的思想來看,一個環必定由小->大,然后再大->小,所以我們令全部小大染色1,大小染色2。
有向圖判環直接拓撲一下就好了。

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<climits>
#include<stack>
#include<vector>
#include<queue>
#include<set>
#include<bitset>
#include<map>
//#include<regex>
#include<cstdio>
#define up(i,a,b)  for(int i=a;i<b;i++)
#define dw(i,a,b)  for(int i=a;i>b;i--)
#define upd(i,a,b) for(int i=a;i<=b;i++)
#define dwd(i,a,b) for(int i=a;i>=b;i--)
//#define local
typedef long long ll;
typedef unsigned long long ull;
const double esp = 1e-6;
const double pi = acos(-1.0);
const int INF = 0x3f3f3f3f;
const int inf = 1e9;
using namespace std;
ll read()
{
	char ch = getchar(); ll x = 0, f = 1;
	while (ch<'0' || ch>'9') { if (ch == '-')f = -1; ch = getchar(); }
	while (ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); }
	return x * f;
}
typedef pair<int, int> pir;
#define lson l,mid,root<<1
#define rson mid+1,r,root<<1|1
#define lrt root<<1
#define rrt root<<1|1
int n, m;
const int N = 5005;
struct {
	int next, to;
}edge[N];
int head[N];
int cnt = 0;
int in[N];
int ans[N];
bool flag = 1;
void addedge(int u, int v)
{
	edge[cnt].to = v;
	edge[cnt].next = head[u];
	head[u] = cnt++;
}
void topo_sort()
{
	queue<int>que;
	int cnt = 0;
	upd(i,1, n)
	{
		if (!in[i])que.push(i), in[i] = -1;
	}
	while (!que.empty())
	{
		cnt++;
		int s = que.front();
		que.pop();
		for (int i = head[s]; ~i; i = edge[i].next)
		{
			int v = edge[i].to;
			in[v]--;
			if (!in[v])que.push(v);
		}
		in[s] = -1;
	}
	//cout << cnt << endl;
	if (cnt == n)flag = 0;
}
int main()
{
	int u, v;
	n = read(), m = read();
	memset(head, -1, sizeof(head));
	up(i, 0, m)
	{
		u = read(), v = read();
		addedge(u, v);
		in[v]++;
		ans[i] = (u < v) + 1;
	}
	topo_sort();
	if (flag) {
		printf("%d\n", 2);
		up(i, 0, m)printf("%d ", ans[i]);
	}
	else {
		printf("%d\n", 1);
		up(i, 0, m)printf("%d ", 1);
	}
}

E:
數論+簡單線段樹。
題意:給出一堆數字,這堆數字good當且僅當,這堆數字的和的每一位,都出現在了這堆數字的某一個數字的對應位置上。
我們假設某兩個數字的同一位置上為a和b(0<=a,b<=9)
我們要使得這個位置的數字不變,那么就有a==0||b == 0,否則,a+b取個位一定是小於a或者b的,那么就需要第三個數字來湊。
因為相加大於十向前進了一位,相當於下一位加1,下一位又是由兩個數字相加得到,這個時候無論是下一位是ai+1 ==0||bi+1 ==0,都因為加了1,所以下一位無法想等。而如果下一位是相加大於十,那么當 ai+1 ==9||bi+1 ==9的時候,加一剛好滿足,但是又有新的問題,帶給了下下位置新的進位,以此類推,一定不滿足情況。因為最高位會變成1,這個最高位肯定是當前兩個數字都無法擁有的。
故滿足的情況只能是,必須一個為零。
那么我們吧1e9拆成10位,個十百千萬這樣的十顆線段樹。
某一段是balance的當且僅當,不為零的數小於等於1。所以我們每一個位置上儲存當前最小的值即可。
題目要求求最小的sum,這個時候我們發現,如果一段中,出現某兩個數字,同時某一位不為零,那么這段區間一定是unbalanced,所以我們只用貪心,找到兩個最小的數字即可。所以我們線段樹還需要維護,次小值。
(啊這種多顆線段樹並且更新繁瑣的拿結構體好方便)

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<climits>
#include<stack>
#include<vector>
#include<queue>
#include<set>
#include<bitset>
#include<map>
//#include<regex>
#include<cstdio>
#define up(i,a,b)  for(int i=a;i<b;i++)
#define dw(i,a,b)  for(int i=a;i>b;i--)
#define upd(i,a,b) for(int i=a;i<=b;i++)
#define dwd(i,a,b) for(int i=a;i>=b;i--)
//#define local
typedef long long ll;
typedef unsigned long long ull;
const double esp = 1e-6;
const double pi = acos(-1.0);
const int INF = 0x3f3f3f3f;
const int inf = 1e9;
using namespace std;
ll read()
{
	char ch = getchar(); ll x = 0, f = 1;
	while (ch<'0' || ch>'9') { if (ch == '-')f = -1; ch = getchar(); }
	while (ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); }
	return x * f;
}
typedef pair<int, int> pir;
#define lson l,mid,root<<1
#define rson mid+1,r,root<<1|1
#define lrt root<<1
#define rrt root<<1|1
int n, m;
const int N = 2e5 + 10;
struct node {
	int m1, m2;
	node operator+(const node &a)const {
		node now = *this;
		node res;
		if (now.m1 < a.m1)res.m1 = now.m1, res.m2 = a.m1;
		else res.m1 = a.m1, res.m2 = now.m1;
		res.m2 = min(res.m2, min(now.m2, a.m2));
		return res;
	}
}tr[N<<2][10];
int a[N];
void pushup(int root)
{
	upd(i, 0, 9)
	{
		tr[root][i] = tr[lrt][i] + tr[rrt][i];
	}
}
void build(int l, int r, int root)
{
	if (l == r)
	{
		int temp = a[l];
		upd(i, 0, 9)
		{
			if(temp%10)
				tr[root][i] = node{ a[l],inf + 1 };
			else tr[root][i] = node{ inf + 1,inf + 1 };
			temp /= 10;
		}
		return;
	}
	int mid = (l + r) >> 1;
	build(lson);
	build(rson);
	pushup(root);
}
void update(int l, int r, int root, int pos)
{
	if (l == r)
	{
		int temp = a[l];
		int cnt = 0;
		upd(i, 0, 9)
		{
			if (temp % 10)
				tr[root][i] = node{ a[l],inf + 1 };
			else tr[root][i] = node{ inf + 1,inf + 1 };
			temp /= 10;
		}
		return;
	}
	int mid = (l + r) >> 1;
	if (pos <= mid)update(lson, pos);
	else update(rson, pos);
	pushup(root);
}
node query(int l, int r, int root, int lf, int rt,int id)
{
	if (lf <= l && r <= rt)
	{
		return tr[root][id];
	}
	node ans = { inf+1,inf+1 };
	int mid = (l + r) >> 1;
	if (lf <= mid)ans = ans + query(lson,lf,rt,id);
	if (rt > mid)ans = ans + query(rson,lf,rt,id);
	return ans;
}
int main()
{
	n = read(), m = read();
	upd(i, 1, n)a[i] = read();
	build(1, n, 1);
	int op;
	int l, r;
	while (m--)
	{
		op = read();
		l = read(), r = read();
		if (op == 1)
		{
			a[l] = r;
			update(1, n, 1, l);
		}
		else
		{
			int sum = 2*inf+3;
			upd(i, 0, 9)
			{
				node ans = { inf + 1,inf + 1 };
				ans = ans + query(1, n, 1, l, r, i);
				if (ans.m1 != inf + 1 && ans.m2 != inf + 1)
					sum = min(sum, ans.m1 + ans.m2);
			}
			if (sum!=2*inf+3)
			{
				printf("%d\n", sum);
			}
			else
				printf("%d\n", -1);
		}
	}
}

最后一道題。。不會。。等以后更厲害了再說吧。。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM