ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

[CSP-S2020] 函数调用 & 贪吃蛇

2021-10-20 15:02:39  阅读:184  来源: 互联网

标签:int void 函数调用 read 贪吃蛇 MAXN inline it2 CSP


函数调用

link

Solution

不知道一年之前我在想什么,明明很sb的一个题目哎。。。

可以想到的是,我们如果可以计算出一个增加节点会贡献多少次就可以直接算了。整体乘的贡献也算在这里就好了。直接topo排序算出进入一个块之前已经全局成了多少就好了。

Code

#include <bits/stdc++.h>>
using namespace std;
 
#define Int register int
#define mod 998244353
#define MAXN 100005

template <typename T> inline void read (T &t){t = 0;char c = getchar();int f = 1;while (c < '0' || c > '9'){if (c == '-') f = -f;c = getchar();}while (c >= '0' && c <= '9'){t = (t << 3) + (t << 1) + c - '0';c = getchar();} t *= f;}
template <typename T,typename ... Args> inline void read (T &t,Args&... args){read (t);read (args...);}
template <typename T> inline void write (T x){if (x < 0){x = -x;putchar ('-');}if (x > 9) write (x / 10);putchar (x % 10 + '0');}
template <typename T> inline void chkmax (T &a,T b){a = max (a,b);}
template <typename T> inline void chkmin (T &a,T b){a = min (a,b);}

vector <int> g1[MAXN],g2[MAXN];
int n,m,tp[MAXN],ris[MAXN],val[MAXN],pos[MAXN],cnt[MAXN],sum[MAXN],deg[MAXN];

int mul (int a,int b){return 1ll * a * b % mod;}
int dec (int a,int b){return a >= b ? a - b : a + mod - b;}
int add (int a,int b){return a + b >= mod ? a + b - mod : a + b;}
void Add (int &a,int b){a = add (a,b);}
void Sub (int &a,int b){a = dec (a,b);}

void topo1 (){
	queue <int> q;
	for (Int i = 0;i <= m;++ i){
		deg[i] = g1[i].size();
		if (!deg[i]) q.push (i);
	}
	while (!q.empty()){
		int u = q.front();q.pop ();
		for (Int v : g2[u]){
			sum[v] = mul (sum[v],sum[u]);
			if (!(-- deg[v])) q.push (v);
		}
	}
}

void topo2 (){
	queue <int> q;
	for (Int i = 0;i <= m;++ i){
		deg[i] = g2[i].size();
		if (!deg[i]) q.push (i);
	}
	while (!q.empty()){
		int u = q.front(),hav = 1;q.pop (),reverse (g1[u].begin(),g1[u].end());
		for (Int v : g1[u]){
			Add (cnt[v],mul (cnt[u],hav)),hav = mul (hav,sum[v]);
			if (!(-- deg[v])) q.push (v);
		}
	}
}

signed main(){
	read (n);
	for (Int i = 1;i <= n;++ i) read (val[i]);
	read (m),sum[0] = cnt[0] = 1;
	for (Int i = 1;i <= m;++ i){
		read (tp[i]),sum[i] = 1;
		if (tp[i] == 1) read (pos[i],ris[i]);
		else if (tp[i] == 2) read (sum[i]);
		else{
			int len;read (len);
			for (Int k = 1,v;k <= len;++ k) read (v),g1[i].push_back (v),g2[v].push_back (i); 
		}
	}
	int Q;read (Q);
	for (Int i = 1,x;i <= Q;++ i) read (x),g1[0].push_back (x),g2[x].push_back (0);
	topo1 (),topo2 ();
	for (Int i = 1;i <= n;++ i) val[i] = mul (val[i],sum[0]);
	for (Int i = 1;i <= m;++ i) if (tp[i] == 1) Add (val[pos[i]],mul (ris[i],cnt[i]));
	for (Int i = 1;i <= n;++ i) write (val[i]),putchar (' ');putchar ('\n');
	return 0;
}

贪吃蛇

link

Solution

考虑对于当前状况,如果最大值吃掉最小值之后不是最小值,那么它就一定会吃掉。因为后面的次大值吃掉之后的最小值一定不必当前最大值减去当前最小值大,后面同理,所以肯定吃不掉,那它就一定会吃。

那么如果吃掉之后是最小值就需要考虑。考虑吃掉了,那么如果次大值吃掉了吃了小鱼的大雨不是最小值,那最大值就不能吃,否则就可以。然后依次类推,找到第一个最大值吃掉不是最小值的,然后判断过程吃的个数的奇偶性即可。

似乎可以用双端队列做到 \(\Theta(nT)\),但是我比较懒,所以就只写了 \(\Theta(Tn\log n)\) 。

Code

#include <bits/stdc++.h>>
using namespace std;
 
#define Int register int
#define MAXN 1000005

template <typename T> inline void read (T &t){t = 0;char c = getchar();int f = 1;while (c < '0' || c > '9'){if (c == '-') f = -f;c = getchar();}while (c >= '0' && c <= '9'){t = (t << 3) + (t << 1) + c - '0';c = getchar();} t *= f;}
template <typename T,typename ... Args> inline void read (T &t,Args&... args){read (t);read (args...);}
template <typename T> inline void write (T x){if (x < 0){x = -x;putchar ('-');}if (x > 9) write (x / 10);putchar (x % 10 + '0');}
template <typename T> inline void chkmax (T &a,T b){a = max (a,b);}
template <typename T> inline void chkmin (T &a,T b){a = min (a,b);}

int n,a[MAXN];

#define pii pair<int,int>
#define se second
#define fi first

void Work (){
	set <pii> S;
	for (Int i = 1;i <= n;++ i) S.insert ({a[i],i});
	if (n == 3){
		if (a[3] - a[1] < a[2]) puts ("3");
		else puts ("1");
	}
	else{
		while (S.size() >= 2){
			auto it1 = S.begin(),it2 = S.end();-- it2;
			if (S.size() == 2){
				puts ("1");
				return ;
			}
			pii f1 = *it1,f2 = *it2,New = {f2.fi - f1.fi,f2.se};
			S.erase (it1),S.erase (it2);
			if ((*S.begin()) < New) S.insert (New);
			else{
				S.insert (f1),S.insert (f2);
				break;
			}
		}
		int fuc = 1,cnt = S.size();
		while (S.size() >= 2){
			if (S.size() == 2){
				fuc ++;
				break;
			}
			else{
				auto it1 = S.begin(),it2 = S.end();-- it2;
				pii f1 = *it1,f2 = *it2,New = {f2.fi - f1.fi,f2.se};S.erase (it1),S.erase (it2);
				if (New < (*S.begin())) fuc ++,S.insert (New);
				else{
					fuc ++;
					break;
				}
			}
		}
		write (cnt - (!(fuc & 1))),putchar ('\n');
	}
}

signed main(){
//	freopen ("snakes4.in","r",stdin);
	int T;read (T);
	read (n);
	for (Int i = 1;i <= n;++ i) read (a[i]);
	Work (),T --;
	while (T --> 0){
		int k;read (k);
		for (Int i = 1,p,v;i <= k;++ i) read (p,v),a[p] = v;
		Work ();
	}
	return 0;
}

标签:int,void,函数调用,read,贪吃蛇,MAXN,inline,it2,CSP
来源: https://www.cnblogs.com/Dark-Romance/p/15428876.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有