zoukankan      html  css  js  c++  java
  • [CSP-S2020] 函数调用 & 贪吃蛇

    函数调用

    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 ('
    ');
    	return 0;
    }
    

    贪吃蛇

    link

    Solution

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

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

    似乎可以用双端队列做到 (Theta(nT)),但是我比较懒,所以就只写了 (Theta(Tnlog 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 ('
    ');
    	}
    }
    
    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;
    }
    
  • 相关阅读:
    Ext.js给form加背景图片
    Linux安装Scala
    idea 无法创建Scala class 选项解决办法汇总
    idea 无法创建Scala class 选项解决办法汇总
    i++和++i的区别,及其线程安全问题
    java面试题
    大数据学习——scala入门程序
    大数据学习——spark安装
    大数据学习——kafka+storm+hdfs整合
    大数据学习——日志监控告警系统
  • 原文地址:https://www.cnblogs.com/Dark-Romance/p/15428876.html
Copyright © 2011-2022 走看看