2018-2019 ICPC Southeastern European Regional Programming Contest (SEERC 2018)

有点难的一场。

题目链接:http://codeforces.com/gym/101964

B:

solver:czq

#!/usr/bin/env python
num = list(map(int, input().split()))
a, b, c, n = num[0], num[1], num[2], num[3]
mod = 2 ** 64

if n % 2 == 0:
    ans = n * (n + 8) * (n - 2) // 24 % mod
else:
    ans = n * (n + 1) * (n - 1) // 24 % mod

if a != b and a != c and b != c:
    ans = ans * 6 % mod
elif a != b or a != c or b != c:
    ans = ans * 3 % mod

print(ans)

C:

solver: czq、zyh

/* basic header */
#include <bits/stdc++.h>
/* define */
#define ll long long
#define pb emplace_back
#define mp make_pair
#define eps 1e-8
#define lson (curpos<<1)
#define rson (curpos<<1|1)
/* namespace */
using namespace std;
/* header end */

const int MAXN = 1100;
int n, m, color[MAXN], vis[MAXN];
vector<int>g[MAXN];

int main() {
    scanf("%d%d", &n, &m);
    for (int i = 0; i <= n; i++) g[i].clear();
    for (int i = 1; i <= n; i++) scanf("%d", &color[i]);
    for (int u, v, i = 0; i < n - 1; i++) {
        scanf("%d%d", &u, &v);
        g[u].pb(v), g[v].pb(u);
    }

    function<int(int, int, int, int)> dfs = [&](int cur, int fa, int depth, int maxDepth)->int{
        int sum = color[cur];
        if (depth >= maxDepth) return sum;
        for (auto v : g[cur]) {
            if (!vis[v] || v == fa) continue;
            sum += dfs(v, cur, depth + 1, maxDepth);
        }
        return sum;
    };

    function<int(int)> check = [&](int maxDepth)->int{
        memset(vis, 0, sizeof vis);
        queue<int>q;
        while (q.size()) q.pop();
        q.push(1);
        vis[1] = 1;
        while (q.size()) {
            int u = q.front();
            q.pop();
            vis[u] = 1;
            if (dfs(u, 0, 0, maxDepth) >= m) return 1;
            for (auto v : g[u]) {
                if (!vis[v]) q.push(v);
            }
        }
        return 0;
    };

    int l = 0, r = n;
    while (l < r) {
        int mid = l + r >> 1;
        if (check(mid)) r = mid;
        else l = mid + 1;
    }
    printf("%d
", r);
    return 0;
}

E:

solver:czq

/* basic header */
#include <bits/stdc++.h>
/* define */
#define ll long long
#define pb emplace_back
#define mp make_pair
#define eps 1e-8
#define lson (curpos<<1)
#define rson (curpos<<1|1)
/* namespace */
using namespace std;
/* header end */

const int MAXN = 1e6 + 10;
struct Fish {
    int x, y, leftMost, rightMost;
    Fish() {}
};
int coor[MAXN], maxRightMost = 0;

int main() {
    int n, m, l;
    scanf("%d%d%d", &n, &m, &l);
    vector<Fish> fishs(n);
    vector<int> num;
    vector<int> fishers(m);
    for (auto &fish : fishs) {
        scanf("%d%d", &fish.x, &fish.y);
        if (fish.y > l) continue;
        int maxDeltaX = l - fish.y;
        int leftMost = max(0, fish.x - maxDeltaX), rightMost = fish.x + maxDeltaX;
        num.push_back(leftMost), num.push_back(rightMost + 1);
        fish.leftMost = leftMost, fish.rightMost = rightMost + 1;
        maxRightMost = max(maxRightMost, rightMost + 1);
    }

    for (auto &fisher : fishers) {
        scanf("%d", &fisher);
        maxRightMost = max(fisher, maxRightMost);
        num.push_back(fisher);
    }

    sort(num.begin(), num.end());
    num.erase(unique(num.begin(), num.end()), num.end());
    maxRightMost = lower_bound(num.begin(), num.end(), maxRightMost) - num.begin();
    for (auto fish : fishs) {
        if (fish.y > l) continue;
        coor[lower_bound(num.begin(), num.end(), fish.leftMost) - num.begin()]++;
        coor[lower_bound(num.begin(), num.end(), fish.rightMost) - num.begin()]--;
    }

    int temp = 0;
    for (int i = 0; i <= maxRightMost; i++) {
        coor[i] += temp;
        temp = coor[i];
    }

    for (auto fisher : fishers)
        printf("%d
", coor[lower_bound(num.begin(), num.end(), fisher) - num.begin()]);
    return 0;
}

G:

solver:czq、zyh

好题。构造几组数据发现答案基本都是4k+1的形式,再开两棵线段树维护相邻行和列颜色数量即可

/* basic header */
#include <bits/stdc++.h>
/* define */
#define ll long long
#define pb emplace_back
#define mp make_pair
#define eps 1e-8
#define lson (curpos<<1)
#define rson (curpos<<1|1)
/* namespace */
using namespace std;
/* header end */
 
const int MAXN = (1 << 20) + 1;
ll totalMatrix = 0, segT[2][MAXN << 2], state[2][21];
int n, m, _size;
 
void update(int id, int pos, int curpos, int curl, int curr, int depth) {
    if (curl == curr) {
        segT[id][curpos] ^= 1;
        return;
    }
    int mid = curl + curr >> 1;
    if (pos <= mid) update(id, pos, lson, curl, mid, depth + 1);
    else update(id, pos, rson, mid + 1, curr, depth + 1);
    if (segT[id][curpos] != -1) state[id][depth]--;
    if (segT[id][lson] == segT[id][rson]) segT[id][curpos] = segT[id][lson];
    else segT[id][curpos] = -1;
    if (segT[id][curpos] != -1) state[id][depth]++;
}
 

struct FastIO {
	static const int LEN=1<<18|1;
	char buf[LEN],wbuf[LEN];
	int s=0,t=0,wpos=0;
	inline int read(){
		int res=((s==t)&&(t=(s=0)+fread(buf,1,LEN,stdin)),s==t?-1:buf[s++]);
		// 注意,是读取到文件末尾时立刻退出程序
		if(res==-1) exit(0);
	return res;
	}
	inline void out(int x){
		wpos==LEN?fwrite(wbuf,1,LEN,stdout),wbuf[0]=x,wpos=1:wbuf[wpos++]=x;
	}
	// 有符号:
	inline int rint(){
		// 根据读入是int还是long long决定x的类型
		int c=read(),x=0,s=1;
		if(c==-1)return 0;
		while(c<=32)c=read();
		if(c=='-')s=-1,c=read();
		while(isdigit(c))x=x*10+c-'0',c=read();
		return x*s;
	}
	inline int ruint(){
		int c=read(),x=0;
		while(c<=32)c=read();
		while(isdigit(c))x=x*10+c-'0',c=read();
		return x;
	}
	inline void rstr(char *str){
		int c=read();
		while(c<=32)c=read();
		while(c>32)*str++=c,c=read();
		*str=0;
	}
	// 根据类型
	inline void wint(long long x){
		// 如果含有负数,取消注释
		// if(x<0)wchar('-'),x=-x;
		char str[24];int n=0;
		while(x||!n)str[n++]='0'+x%10,x/=10;
		while(n--)out(str[n]);
	}
	inline void wchar(char str){
		out(str);
	}
	inline void wstr(const char *s){
		while(*s)out(*s++);
	}
	inline void over(){
		if(wpos)fwrite(wbuf,1,wpos,stdout),wpos=0;
	}
	~FastIO(){
		if(wpos)fwrite(wbuf,1,wpos,stdout),wpos=0;
	}
}io;

 
int main() {
    _size=io.rint();
    m=io.rint();
    //read(_size); read(m);
    n = (1 << _size);
    for (int i = 0; i < _size; i++) {
        state[0][i + 1] = state[1][i + 1] = (1 << i);
        totalMatrix += (1LL << (i << 1));
    }
    for (int i = 0; i < m; i++) {
        int id, x; //read(id); read(x);
        id=io.rint();
        x=io.rint();
        update(id, x, 1, 1, n, 1);
        ll tmp = 0;
        for (int i = 1; i <= _size; i++)
            tmp += state[0][i] * state[1][i];
        io.wint(4ll * (totalMatrix - tmp) + 1ll);
        io.wchar('
');
    }
    return 0;
}

H

solver:lzh、zyh

题意是这样的:有n个人m个愿望,每个愿望都是一个二元组(x,y),代表第x个人不希望第y个人快乐。判断一个人是否快乐的条件是:这个人至少有一个愿望被满足。问:当至少(m/4+1)个愿望被满足时,哪些人是快乐的。

由于数据范围很大,所以我们不可能真的去找。做法是先rand每个人的情绪状态(是否快乐),然后根据这些情绪状态去遍历愿望,check有多少愿望被满足。不满足就继续rand。

这种做法的合理性在于m最大值仅仅为n的两倍,算不上稠密。否则check一次代价很大。

#include <bits/stdc++.h>
using namespace std;
typedef pair<int, int> pii;
#define ff first
#define ss second
#define mp make_pair

int a[200010], b[200010], tmp[200010], ans[200010];
//
int main()
{
    srand(time(0));
    int T;
    scanf("%d", &T);
    while (T--) {
        int n, m;
        scanf("%d%d", &n, &m);
        int K = m / 4 + 1, cur = 0;
        for (int i = 1, x, y; i <= m; i++)
            scanf("%d%d", &a[i], &b[i]);
        while (1) {
            cur = 0;
            for (int i = 1; i <= n; i++) {
                tmp[i] = rand() & 1;
            }
            for (int i = 1; i <= m; i++)
                ans[i] = 0;
            for (int i = 1; i <= m; i++)
                if (tmp[a[i]] && !tmp[b[i]])
                    cur++,ans[i]++;
            if (cur >= K)
                break;
        }
        printf("%d
", cur);
        for (int i = 1; i <= m; i++)
            if (ans[i])
                printf("%d ", i);
        printf("
");
    }
}

I

solver:czq、zyh

略诡异的题目。由于其偏序性质,可以考虑构建有向图,拓扑排序后dp去做。

/* basic header */
#include <bits/stdc++.h>
/* define */
#define ll long long
#define pb emplace_back
#define mp make_pair
#define eps 1e-8
#define lson (curpos<<1)
#define rson (curpos<<1|1)
/* namespace */
using namespace std;
/* header end */

const int MAXN = 110;
int n, m, deg[MAXN], _rank[MAXN], vis[MAXN];
ll dp[MAXN];

int main() {
    scanf("%d%d", &n, &m);
    for (int u, v, i = 0; i < m; i++) {
        scanf("%d%d", &u, &v);
        u--, v--, deg[min(u, v)]++;
    }
    for (int i = 0; i < n; i++)
        for (int j = 0; j < n; j++)
            if (!vis[j])
                if (deg[i]) deg[i]--;
                else {
                    _rank[i] = j;
                    vis[j] = 1;
                    break;
                }
    _rank[n] = n;
    for (int i = 0; i <= n; i++) {
        for (int maxRank = -1, j = i - 1; j >= 0; j--)
            if (_rank[j] > maxRank && _rank[i] > _rank[j])
                maxRank = _rank[j], dp[i] += dp[j];
        dp[i] = max(1LL, dp[i]);
    }
    printf("%lld
", dp[n]);
    return 0;
}
原文地址:https://www.cnblogs.com/JHSeng/p/12831858.html