zoukankan      html  css  js  c++  java
  • atcoder ABC233

    B

    image

    题意

    给一个字符串, 可以把第一个字母移到最后, 也可以把最后一个字母放第一个, 问字典序最大最小的字符串。

    题解

    把第一个放最后一个, 相当于把最后一个放第一个执行n-1次, 那么我们不妨只进行第一步操作, 把所有的结果都算出来, 排序即可; 注:提取string的子串方法:a.substr(i, j); 从第i位开始, 长度为j的字符串(开头是0);

    D

    image

    题意

    构造一个n的全排列, 使(a_i)(b_i)前面;

    题解

    非常简单, 建边判环即可, 判环和记录答案都可以用topsort, 不过统计答案的时候要用堆优化, 应该可以写到一个函数里面

    代码
    #include <bits/stdc++.h>
    
    using namespace std;
    
    typedef long long ll;
    const int INF = 0x3f3f3f3f;
    const int N = 2e5 + 10;
    const int M = 5e3 + 10;
    const int eps = 1e-6; 
    
    template < typename T > inline void read(T &x) {
    	x = 0; T ff = 1, ch = getchar();
    	while (!isdigit(ch)) {
    		if (ch == '-') ff = -1;
    		ch = getchar(); 
    	}
    	while (isdigit(ch)) {
    		x = (x << 1) + (x << 3) + (ch ^ 48);
    		ch = getchar(); 
    	}
    	x *= ff; 
    }
    
    int n, m, c[N], du[N], vi[N];
    map < int, int > p[N]; 
    vector < int > v[N], a;
    
    inline bool topsort() {
    	queue < int > q;
    	for (int i = 1; i <= n; ++i) 
    		if (c[i] == 0) q.push(i);
    	while (!q.empty()) {
    		int x = q.front();
    		q.pop();
    		for (int i = 0; i < v[x].size(); ++i) {
    			int y = v[x][i];
    			--c[y];
    			if (c[y] == 0) q.push(y); 
    		}
    	}
    	for (int i = 1; i <= n; ++i) 
    		if (c[i]) return false;
    	return true;
    } 
    
    inline void solve() {
    	priority_queue < int > q;
    	for (int i = 1; i <= n; ++i) 
    		if (du[i] == 0) q.push(-i);
    	while (!q.empty()) {
    		int x = -q.top();
    		q.pop();
    		a.push_back(x);
    		for (int i = 0; i < v[x].size(); ++i) {
    			int y = v[x][i];
    			--du[y];
    			if (du[y] == 0) q.push(-y);
    		}
    	}
    	for (int i = 0; i < n; ++i) printf("%d ", a[i]);
    }
    
    int main() { 
    	read(n), read(m);
    	for (int i = 1; i <= m; ++i) {
    		int x, y;
    		read(x), read(y);
    		if (p[x][y]) continue;
    		p[x][y] = true;
    		v[x].push_back(y);
    		++du[y];
    		++c[y];
    	} 
    	if (!topsort()) puts("-1");
    	else solve();
    	return 0;
    }
    
    

    E

    image

    题意

    题目不是很好理解, 有个x*y的网格, 要放入三个面积不小于a, b, c且边长都为整数的矩形, 判断是否成立。

    题解

    当有两个矩形的时候, 存在一条线, 把两个矩形分开。 当三个矩形的时候, 存在一条线, 分成一边一个矩形,一边两个矩形。 那我们就枚举这个矩形,在枚举x或y,使这条边充分利用, 算出len=(lceilfrac{S}{x} ceil), 或 len=(lceilfrac{S}{y} ceil), 从而把边长减去len, 转换成两个矩形的问题, 同上

    代码
    #include <bits/stdc++.h>
    
    using namespace std;
    
    typedef long long ll;
    const int INF = 0x3f3f3f3f;
    const int N = 2e5 + 10;
    const int M = 5e3 + 10;
    const int eps = 1e-6; 
    
    template < typename T > inline void read(T &x) {
    	x = 0; T ff = 1, ch = getchar();
    	while (!isdigit(ch)) {
    		if (ch == '-') ff = -1;
    		ch = getchar(); 
    	}
    	while (isdigit(ch)) {
    		x = (x << 1) + (x << 3) + (ch ^ 48);
    		ch = getchar(); 
    	}
    	x *= ff; 
    }
    
    ll n, m, a, b, c;
    
    inline bool solve2(ll x, ll y, ll u, ll v) {
    	for (int i = 0; i < 2; ++i) {
    		ll len = (u + x - 1) / x;
    		if (len < y && x * (y - len) >= v) return true;
    		swap(x, y);
    	}
    	return false;
    }
    
    inline bool solve3(ll x, ll y, ll u, ll v, ll w) {
    	for (int i = 0; i < 2; ++i) {
    		for (int j = 0; j < 3; ++j) {
    			ll len = (u + x - 1) / x;
    			if (len < y && solve2(x, y - len, v, w)) return true;
    			swap(u, v);
    			swap(v, w);
    		} 
    		swap(x, y);
    	}
    	return false;
    }
    
    int main() { 
    	read(n), read(m), read(a), read(b), read(c);
    	puts(solve3(n, m, a, b, c) ? "Yes" : "No");
    	return 0;
    }
    
    

    F

    在看这道题之前, 我们先引入一道题
    题目
    我们再引入一个题解
    题解
    题解是链上的做法, 引申到树上即可.(吐槽一波, csp我竟然看错题了)
    上题
    image
    题目的意思是, 有一个长度为n的括号序列, 有两个操作, 一是交换l, r的括号, 二是求l到r之间是不是完美匹配. 有了上面的铺垫, 我们很显然知道, 一段区间是合法的, 必须满足, a[l - 1] = a[r], 且a[l ~ r - 1] >= a[l - 1] (a[r]), 那我们交换两个不同的括号有什么影响呢, 假如是左边的左括号和右边的右括号交换, 那么a[l ~ r - 1], 全部减去2, 反之同理, 看到这个, 那么我们就知道要用数据结构来维护这个a数组了, 线段树显然可以, 当然需要懒标记.

    代码
    #include <bits/stdc++.h>
    
    using namespace std;
    
    //typedef long long ll;
    const int INF = 0x3f3f3f3f;
    const int N = 2e5 + 10;
    const int M = 1e6 + 10;
    //const int mod = 1e9 + 7;
    //const double eps = 1e-6; 
    
    template < typename T > inline void read(T &x) {
    	x = 0; T ff = 1, ch = getchar();
    	while (!isdigit(ch)) {
    		if (ch == '-') ff = -1;
    		ch = getchar(); 
    	}
    	while (isdigit(ch)) {
    		x = (x << 1) + (x << 3) + (ch ^ 48);
    		ch = getchar(); 
    	}
    	x *= ff; 
    }
    
    char ch[N];
    int n, m, a[N];
    struct tree {
    	int l, r;
    	int dat, lazy;
    }t[N << 2];
    
    inline void build(int x, int l, int r) {
    	t[x].l = l, t[x].r = r;
    	if (l == r) {
    		t[x].dat = a[l];
    		return;
    	}
    	int mid = l + r >> 1;
    	build(x << 1, l, mid);
    	build(x << 1 | 1, mid + 1, r);
    	t[x].dat = min(t[x << 1].dat, t[x << 1 | 1].dat);
    }
    
    inline void push_down(int x) {
    	if (t[x].lazy != 0) {
    		t[x << 1].lazy += t[x].lazy;
    		t[x << 1 | 1].lazy += t[x].lazy;
    		t[x << 1].dat += t[x].lazy;
    		t[x << 1 | 1].dat += t[x].lazy;
    //		t[x].dat = min(t[x << 1].dat, t[x << 1 | 1].dat);
    		t[x].lazy = 0; 
    	}
    } 
    
    inline void change(int x, int L, int R, int c) {
    	int l = t[x].l, r = t[x].r;
    	if (L <= l && R >= r) {
    		t[x].dat += c;
    		t[x].lazy += c;
    		return;
    	}
    	push_down(x);
    	int mid = l + r >> 1;
    	if (mid >= L) change(x << 1, L, R, c);
    	if (mid < R) change(x << 1 | 1, L, R, c); 
    	t[x].dat = min(t[x << 1].dat, t[x << 1 | 1].dat);
    }
    
    inline int query(int x, int L, int R) {
    	int l = t[x].l, r = t[x].r;
    	if (l >= L && r <= R) return t[x].dat;
    	push_down(x);
    	int ans = INF;
    	int mid = l + r >> 1;
    	if (mid >= L) ans = min(ans, query(x << 1, L, R));
    	if (mid < R) ans = min(ans, query(x << 1 | 1, L, R));
    //	t[x].dat = (t[x << 1].dat, t[x << 1 | 1].dat);
    	return ans;
    }
    
    int main() { 
    	read(n); read(m);
    	scanf("%s", ch + 1);
    	for (int i = 1; i <= n; ++i) {
    		if (ch[i] == '(') a[i] = a[i - 1] + 1;
    		else a[i] = a[i - 1] - 1;
    	} 
    	build(1, 0, n);
    	for (int i = 1; i <= m; ++i) {
    		int op, l, r;
    		read(op), read(l), read(r);
    		if (op == 1) {
    			if (ch[l] == ch[r]) continue;
    			if (ch[l] == '(') change(1, l, r - 1, -2);
    			else change(1, l, r - 1, 2);
    			swap(ch[l], ch[r]); 
    		} else {
    			int x, y, z;
    			x = query(1, l - 1, l - 1); 
    			y = query(1, l, r);
    			z = query(1, r, r);
    			if (x == y && y == z) puts("Yes");
    			else puts("No");
    		}
    	}
    	return 0;
    }
    
    
  • 相关阅读:
    jsmin Javascript 的小巧的压缩工具
    pChart 支持中文显示
    使用 SyntaxHighlighter 实现代码高亮
    Linux Ubuntu 下阅读 CHM
    QueryPath Method Summary_方法速查手册
    QueryPath PHP 中的 jQuery
    SQL SELECT DISTINCT 语句
    写网页内容需要注意些什么?
    jQuery UI 弹出注册窗口_练习
    Smarty 中的 Foreach
  • 原文地址:https://www.cnblogs.com/AK-ls/p/15427753.html
Copyright © 2011-2022 走看看