zoukankan      html  css  js  c++  java
  • Gym 102501部分题解

    Gym - 102501D Gnalcats

    https://codeforces.com/gym/102501/problem/D

    题意

    给两种栈操作判断是否相等,如果两个操作都fail,也认为相等

    Solution

    模拟,每个氨基酸一个hash值。通过判断最后栈元素是否对应hash相等,判断操作是否相等

    #include <cstdio>
    #include <stack>
    #include <set>
    #include <cmath>
    #include <map>
    #include <time.h>
    #include <vector>
    #include <iostream>
    #include <string>
    #include <cstring>
    #include <algorithm>
    //#include <memory.h>
    #include <cstdlib>
    #include <queue>
    #include <iomanip>
    #include <cassert>
    #include <unordered_map>
    #define P pair<int, int>
    #define LL long long
    #define LD long double
    #define PLL pair<LL, LL>
    #define mset(a, b) memset(a, b, sizeof(a))
    #define rep(i, a, b) for (int i = a; i < b; i++)
    #define PI acos(-1.0)
    #define random(x) rand() % x
    #define debug(x) cout << #x << " " << x << "
    "
    using namespace std;
    const int inf = 0x3f3f3f3f;
    const LL __64inf = 0x3f3f3f3f3f3f3f3f;
    #ifdef DEBUG
    const int MAX = 2e3 + 50;
    #else
    const int MAX = 1e6 + 50;
    #endif
    const int mod = 1e9 + 7;
    void file_read() {
    #ifdef DEBUG
    	freopen("in", "r", stdin);
    	// freopen("out", "w", stdout);
    #endif
    }
    
    #define ULL unsigned long long
    
    struct DNA
    {
    	struct Node
    	{
    		int l, r;
    		unsigned LL val;
    		Node(){}
    		Node(int l, int r, unsigned LL val) : l(l), r(r), val(val) {}
    		bool complex() const {
    			return l and r;
    		}
    	}tr[MAX];
    	stack<int> stk;
    	int tot;
    	int num;
    	DNA() : tot(1), num(1) {
    		for(int i = 1; i <= (int)1e5; i++) {
    			tr[tot] = Node(0, 0, num++);
    			stk.push(tot);
    			tot++;
    		}
    	}
    	ULL hash(int u, int v) {
    		ULL base = 131;
    		return tr[u].val * base + tr[v].val;
    	}
    	bool op_C() {
    		auto u = stk.top();
    		tr[tot] = tr[u];
    		stk.push(tot);
    		tot++;
    		return true;	
    	}
    	bool op_D() {
    		stk.pop();
    		return true;
    	}
    	bool op_L() {
    		auto u = stk.top(); stk.pop();
    		if(!tr[u].complex())  
    			return false;	
    		// tr[tot] = tr[tr[u].l];
    		// stk.push(tot);
    		stk.push(tr[u].l);
    		return true;
    	}
    	bool op_P() {
    		auto u = stk.top(); stk.pop();
    		auto v = stk.top(); stk.pop();
    		tr[tot] = Node(u, v, hash(u, v));
    		stk.push(tot);
    		tot++;
    		return true;
    	}
    	bool op_R() {
    		auto u = stk.top(); stk.pop();
    		if(!tr[u].complex()) 
    			return false;
    		// tr[tot] = tr[tr[u].r];
    		// stk.push(tot++);
    		stk.push(tr[u].r);
    		return true;
    	}
    	bool op_S() {
    		auto u = stk.top(); stk.pop();
    		auto v = stk.top(); stk.pop();
    		stk.push(u);
    		stk.push(v);
    		return true;
    	}
    	bool op_U() {
    		auto u = stk.top(); stk.pop();
    		if(!tr[u].complex()) 
    			return false;
    		stk.push(tr[u].r);
    		stk.push(tr[u].l);
    		return true;
    	}
    	bool op(const string &s) {
    		bool res = true;
    		for(auto c : s) {
    			switch (c)
    			{
    			case 'C':res &= op_C(); break;
    			case 'D':res &= op_D(); break;
    			case 'L':res &= op_L(); break;
    			case 'P':res &= op_P(); break;
    			case 'R':res &= op_R(); break;
    			case 'S':res &= op_S(); break;
    			case 'U':res &= op_U(); break;
    			default:
    				break;
    			}
    		}
    		return res ;
    	}
    };
    
    DNA A, B;
    int main() {
    	file_read();
    	string s, t;
    	cin >> s >> t;
    	A = DNA();
    	B = DNA();
    	bool a = A.op(s);
    	bool b = B.op(t);
    	if(a ^ b) {
    		puts("False");
    		return 0;
    	}
    	if(!a and !b) {
    		puts("True");
    		return 0;
    	}
    	while(!A.stk.empty() and !B.stk.empty()) {
    		auto u = A.stk.top(); A.stk.pop();
    		auto v = B.stk.top(); B.stk.pop();
    		if(A.tr[u].val != B.tr[v].val) {
    			puts("False");
    			return 0;
    		}
    	}
    	if(!A.stk.empty() || !B.stk.empty()) {
    		puts("False");
    		return 0;
    	}
    	puts("True");
    	return 0;
    }
    

    Gym - 102501J

    https://codeforces.com/gym/102501/problem/J

    题意

    给一个树的中序遍历序列,判断有多少满足类似小根堆的树,(n<=1e5)

    Solution

    • 直接dp一定会超时
    • 考虑根可能在的位置,即当前最小元素的位置
    • 考虑选这些元素为根会有哪些树,就可以发现当前的最小元素将序列分成子段,当前元素作为根的种类数是卡特兰数
    • 因此递归解决这个问题,每次用最小元素分割当前序列,最后其实就是一些卡特兰数的乘积
    • 用单调栈会更优美一点
    #include <cstdio>
    #include <stack>
    #include <set>
    #include <cmath>
    #include <map>
    #include <time.h>
    #include <vector>
    #include <iostream>
    #include <string>
    #include <cstring>
    #include <algorithm>
    //#include <memory.h>
    #include <cstdlib>
    #include <queue>
    #include <iomanip>
    #include <cassert>
    #include <unordered_map>
    #define P pair<int, int>
    #define LL long long
    #define LD long double
    #define PLL pair<LL, LL>
    #define mset(a, b) memset(a, b, sizeof(a))
    #define rep(i, a, b) for (int i = a; i < b; i++)
    #define PI acos(-1.0)
    #define random(x) rand() % x
    #define debug(x) cout << #x << " " << x << "
    "
    using namespace std;
    const int inf = 0x3f3f3f3f;
    const LL __64inf = 0x3f3f3f3f3f3f3f3f;
    #ifdef DEBUG
    const int MAX = 2e3 + 50;
    #else
    const int MAX = 2e6 + 500;
    #endif
    const int mod = 1e9 + 7;
    void file_read() {
    #ifdef DEBUG
    	freopen("in", "r", stdin);
    	// freopen("out", "w", stdout);
    #endif
    }
    
    
    int a[MAX];
    LL fact[MAX];
    LL inv[MAX];
    map<int, vector<int>> pos;
    LL qpow(LL x, LL n) {
    	LL res = 1;
    	while(n) {
    		if(n & 1) {
    			res = res * x % mod;
    		}
    		x = x * x % mod;
    		n >>= 1;
    	}
    	return res;
    }
    LL f(LL x) {
    	return fact[2*x] * inv[x] % mod * inv[x+1] % mod;
    }
    
    int main() {
    	file_read();
    	int n; 
    	scanf("%d", &n);
    	for(int i = 1; i <= n; i++) {
    		scanf("%d", &a[i]);
    	}
    	fact[0] = 1;
    	for(int i = 1; i < MAX; i++) fact[i] = 1LL * fact[i-1] * i % mod;
    	inv[MAX-1] = qpow(fact[MAX-1], mod-2);
    	for(int i = MAX-2; i >= 1; i--) inv[i] = 1LL * (i+1) * inv[i+1] % mod;
    	inv[0] = 1;
    	LL res = 1;
    	stack<int> stk;
    	for(int i = 1; i <= n; i++) {
    		if(stk.empty()) {
    			stk.push(a[i]);
    			continue;
    		}
    		int cnt = 0;
    		int cur = inf;
    		while(!stk.empty() and stk.top() > a[i]) {
    			if(stk.top() == cur) {
    				cnt++;
    			}
    			else {
    				res = res * f(cnt) % mod;
    				cnt = 1;
    				cur = stk.top();
    			}
    			stk.pop();
    		}
    		stk.push(a[i]);
    		res = res * f(cnt) % mod;
    	}
    	int cur = inf;
    	int cnt = 0;
    	while(!stk.empty()) {
    		if(stk.top() == cur) {
    			cnt++;
    		}
    		else {
    			res = res * f(cnt) % mod;
    			cur = stk.top();
    			cnt = 1;
    		}
    		stk.pop();
    	}
    	res = res * f(cnt ) % mod;
    	printf("%lld
    ", res);
    }
    
  • 相关阅读:
    IPC之PIPE
    MSChart的研究(转)
    计算机信息类ComputerInfo(车)
    c# 操作Word总结(车)
    js跳转页面(转)
    textarea中的回车识别问题
    js的页面传值cookie.session
    destoon使用
    vscode 配置php
    vscode开发c#
  • 原文地址:https://www.cnblogs.com/sidolarry/p/13592029.html
Copyright © 2011-2022 走看看