Codeforces Round #536 (Div. 2) 6/6

A

暴力

#include <bits/stdc++.h>

using namespace std;

int a[1000][1000];

int main() {
	int n;
	cin >> n;
	for (int i = 1; i <= n; ++i) {
		string s;
		cin >> s;
		for (int j = 0; j < n; ++j) 
			if (s[j] == 'X')
				a[i][j + 1] = 1;
	}
	int ans = 0;
	for (int i = 1; i <= n; ++i)
		for (int j = 1; j <= n; ++j)
			if (a[i][j] == 1) {
				if (a[i - 1][j - 1] && a[i - 1][j + 1] && a[i + 1][j - 1] && a[i + 1][j + 1])
					++ans;
			}
	cout << ans << '\n';
}

B

题没读懂XD,结果1.5h交完E发现B是一个WA,发现没看清3,哭泣,还好unrated了
就开个栈把最小值存进去依次出栈就好了
复杂度显然线性

#include <bits/stdc++.h>

using namespace std;

using ll = long long;
using pii = pair<int, int>;

int const N = 100005;

pii stap[N];
stack<pii> sta;
int a[N];
ll c[N];
int n, m;

int main() {
	cin >> n >> m;
	for (int i = 1; i <= n; ++i) 
		cin >> a[i];
	for (int i = 1; i <= n; ++i) {
		cin >> c[i];
		stap[i] = make_pair(c[i], i);
	}

	sort(stap + 1, stap + n + 1);
	for (int i = n; i >= 1; --i)
		sta.push(stap[i]);

	for (int i = 1; i <= m; ++i) {
		int x, y;
		cin >> x >> y;
		ll ans = 0;
		if (a[x]) {
			int ser = min(a[x], y);
			ans += ser * c[x];
			y -= ser;
			a[x] -= ser;
		}
		while (sta.empty() == 0 && y) {
			auto p = sta.top();
			int sm = p.second;
			int ser = min(a[sm], y);
			ans += ser * c[sm];
			y -= ser;
			a[sm] -= ser;
			if (a[sm] == 0)
				sta.pop();
		}
		if (y)
			ans = 0;
		cout << ans << '\n';
	}
}

C

为什么没有先开C(x
就倒过来和正过来组合就好了,证明大概是不等式搞搞就完了


 #include <bits/stdc++.h>

using namespace std;

using ll = long long;

int const N = 300005;

ll sqr(ll x) {
	return x * x;
}

ll a[N];

int main() {
	int n;
	cin >> n;
	for (int i = 1; i <= n; ++i)
		cin >> a[i];
	sort(a + 1, a + n + 1);
	ll ans = 0;
	for (int i = 1, j = n; i <= j; ++i, --j) 
		ans += sqr(a[i] + a[j]);
	cout << ans << '\n';
}

D

傻逼贪心(怎么这么简单

#include <bits/stdc++.h>

using namespace std;

int const N = 100005;

struct edge {
	int y, next;
}e[N << 1];
int last[N], ne = 0;

void add(int x, int y) {
	e[++ne].y = y;
	e[ne].next = last[x];
	last[x] = ne;
}

void add2(int x, int y) {
	add(x, y);
	add(y, x);
}

bool vis[N];
int n, m;

int main() {
	cin >> n >> m;
	for (int i = 1; i <= m; ++i) {
		int x, y;
		cin >> x >> y;
		add2(x, y);
	}
	vector<int> ans;
	ans.push_back(1);
	vis[1] = 1;
	priority_queue<int, vector<int>, greater<int> > Q;
	auto Qadd = [&] (int x) {
		for (int i = last[x]; i != 0; i = e[i].next) {
			int y = e[i].y;
			if (vis[y])
				continue;
			vis[y] = 1;
			Q.push(y);
		}
	};
	Qadd(1);
	while (Q.empty() == 0) {
		int sm = Q.top();
		Q.pop();
		ans.push_back(sm);
		Qadd(sm);
	}
	for (auto& v : ans) 
		cout << v << ' ';
	cout << '\n';
}

E

傻逼DP(怎么这场这么简单

#include <bits/stdc++.h>

using namespace std;

using ll = long long;

int const N = 100005;
int const M = 204;

struct event {
	bool op;
	int id;
};

int s[N], t[N], d[N], w[N];
ll f[N][M];
int n, m, cand;

vector<event> ev[N];

struct node {
	int d, w;
	bool operator<(node const& b) const {
		if (w == b.w)
			return d > b.d;
		return w > b.w;
	}
};

int main() {
	cin >> n >> m >> cand;
	for (int i = 0; i < cand; ++i) {
		cin >> s[i] >> t[i] >> d[i] >> w[i];
		ev[s[i]].push_back(event{1, i});
		ev[t[i] + 1].push_back(event{0, i});
	}
	multiset<node> S;
	ll ans = 1e15;
	memset(f, 127 / 2, sizeof(f));
	f[1][0] = 0;
	for (int i = 1; i <= n; ++i) {
		for (auto const& e : ev[i]) {
			if (e.op == 1) 
				S.insert(node{ d[e.id], w[e.id] });
			else
				S.erase(S.find(node{ d[e.id], w[e.id] }));
		}
		for (int j = 0; j <= min(i - 1, m); ++j) {
			if (S.empty() == 0) {
				auto fir = *S.begin();
				f[fir.d + 1][j] = min(f[fir.d + 1][j], f[i][j] + fir.w);
			} else 
				f[i + 1][j] = min(f[i + 1][j], f[i][j]);
			if (j == m)
				continue;
			f[i + 1][j + 1] = min(f[i + 1][j + 1], f[i][j]);
		}
	}
	for (int i = 0; i <= m; ++i) 
		ans = min(ans, f[n + 1][i]);
	cout << ans << '\n';
}

F

两边对 f k f_k fk取对数,然后就线性递推出 f n ′ f_n&#x27; fn
这样推出的 f n = f k f n ′ f_n=f_k ^{f_n&#x27;} fn=fkfn
然后就是一个傻逼的N次剩余了
然后抄个板子
当然这里只要求一个解,所以我们就直接如果找到解就退出好了
不然一下子就T了
这场虽然unrated,但是延时了40分钟,如果不是把matrix的矩阵的ll写成了int
就能收获第一次AK了(哭唧唧

#include <bits/stdc++.h>

using namespace std;

#define SZ(x) ((ll)(x).size())

using ll = long long;

ll const mod1 = 998244352;
ll const mod = 998244353;

struct matrix {
	int m;
	ll a[101][101];

	matrix() {
		memset(a, 0, sizeof(a));
	}
	matrix(int _m) {
		memset(a, 0, sizeof(a));
		m = _m;
	}
	matrix(int _m, int k) {
		m = _m;
		for (int i = 1; i <= m; ++i)
			for (int j = 1; j <= m; ++j)
				if (i != j)
					a[i][j] = 0;
				else
					a[i][j] = k;
	}

	matrix operator*(matrix const& b) const {
		auto ret = matrix(m);
		for (int k = 1; k <= m; ++k) 
			for (int i = 1; i <= m; ++i) 
				for (int j = 1; j <= m; ++j) {
					ret.a[i][j] += a[i][k] * b.a[k][j];
					ret.a[i][j] %= mod1;
				}
		return ret;
	}
};

matrix KSM(matrix a, ll k) {
	auto ret = matrix(a.m, 1);
	while (k) {
		if (k & 1) 
			ret = ret * a;
		a = a * a;
		k >>= 1;
	}
	return ret;
}

ll GetFNp() {
	int m;
	cin >> m;
	static int b[106];
	for (int i = 1; i <= m; ++i)
		cin >> b[i];

	matrix X(m);
	X.a[1][m] = 1;

	matrix A(m);
	for (int i = 1; i < m; ++i)
		A.a[i + 1][i] = 1;
	for (int i = 1, j = m; i <= m; ++i, --j)
		A.a[i][m] = b[j];

	int n;
	cin >> n;
	X = X * KSM(A, n - m);
	return X.a[1][m];
}

ll mul(ll a,ll b,ll m){
    ll ret = 0;
    a %= m;
    while(b){
        if(b & 1) ret = (ret + a) % m;
        a = (a + a) % m;
        b >>= 1;
    }
    return ret;
}
ll a_b_MOD_c(ll a,ll b,ll m){
    ll ret = 1;
    a %= m;
    while(b){
        if(b&1) ret = mul(ret,a,m);
        a = mul(a,a,m);
        b >>= 1;
    }
    return ret;
}
 
ll ext_gcd(ll a,ll b,ll &x,ll &y){
    if(b==0) { x=1, y=0; return a; }
    ll ret= ext_gcd(b,a%b,y,x);
    y-= a/b*x;
    return ret;
}

vector<ll> a;
bool g_test(ll g,ll p){
    for (ll i = 0; i < SZ(a); ++i)
        if(a_b_MOD_c(g,(p-1)/a[i],p)==1)
            return 0;
    return 1;
}
ll pri_root(ll p){
    a.clear();
    ll tmp=p-1;
    for(ll i=2;i<=tmp/i;++i)
        if(tmp%i==0){
            a.push_back(i);
            while(tmp%i==0)
                tmp/=i;
        }
    if(tmp!=1)
        a.push_back(tmp);
    ll g=1;
    while(1) {
        if(g_test(g,p))
            return g;
        ++g;
    }
}

const int HASH_MOD=9876543;
ll key[HASH_MOD], val[HASH_MOD];
int head[HASH_MOD], nxt[HASH_MOD];
struct Hash{
    int tot;
    void init(){
        memset(head, -1, sizeof(head));
        tot = 0;
    }
    void insert(ll x, ll y){
        int k = x % HASH_MOD;
        key[tot] = x;
        val[tot] = y;
        nxt[tot] = head[k];
        head[k] = tot++;
    }
    ll find(ll x){
        int k = x % HASH_MOD;
        for(int i = head[k]; i != -1; i = nxt[i])
            if(key[i] == x)
                return val[i];
        return -1;
    }
}hs;

ll log_mod(ll a, ll b, ll m){
    hs.init();
    ll s = ceil(sqrt(m + 0.5));
    ll cur = 1;
    for (int i = 0; i < s; ++i){
        if(hs.find(cur)==-1) hs.insert(cur,i);
        cur = cur * a % m;
    }
 
    ll v = a_b_MOD_c(a, (m - s - 1 + m) % m, m);
    for(int i = 0; i < s; ++i){
        ll tmp = hs.find(b);
        if(tmp!=-1)
            return s * i + tmp;
        b=b*v%m;
    }
    return -1;
}

vector<ll> residue(ll p, ll N, ll a) {
    ll g = pri_root(p);
	g %= p;
    ll m = log_mod(g, a, p);
    vector<ll> ret;
    if(a == 0){
        ret.push_back(0);
        return ret;
    }
    if(m == -1)
        return ret;
    ll A = N, B = p - 1, C = m, x, y;
    ll d = ext_gcd(A, B, x, y);
    if(C % d != 0) return ret;
    x = x * (C / d) % B;
    ll delta = B / d;
    for(int i = 0; i < d; ++i){
        x = ((x + delta) % B + B) % B;
        ret.push_back(a_b_MOD_c(g, x, p));
		if (SZ(ret))
			return ret;
    }
    sort(ret.begin(), ret.end());
    ret.erase(unique(ret.begin(), ret.end()), ret.end());
    return ret;
}

int main() {
	ll N = GetFNp();
	ll x;
	cin >> x;
	auto ans = residue(mod, N, x);
	if (ans.size()) 
		cout << ans[0] << '\n';
	else
		cout << -1 << '\n';
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值