首页 > 其他分享 >AtCoder Beginner Contest 344

AtCoder Beginner Contest 344

时间:2024-03-09 23:55:21浏览次数:25  
标签:AtCoder Beginner int rep 一次函数 344 fi ll define

AtCoder Beginner Contest 344

ABCD 略
E Insert or Erase

手写链表调了这么久。。链表模板。

F Earn to Advance

考虑 DP,但是我们发现不是很好转移,然后我们发现 \(n \le 80\),我们观察一下题目的性质。
如果路径确定了,那么我们肯定会在最大值的地方使劲加到终点为止。
那么我们考虑直接按照那个路径最大值用 \(O(n^4)\) 来跳着转移。
我们 \(O(n^4)\) 预处理出所有两点之间的最小花费。
然后在记一个 \(dp_{i,j}\) 表示从 \((1,1)\) 走到 \((i,j)\) 的最小步数,还有一个 \(s_{i,j}\) 表示在最小步数的情况下最大的剩余值,然后我们用 \((i,j)\) 去更新 \(\forall (a,b)(i\le a \le n, j\le b \le n)\),转移就比较简单了。

G Points and Comparison

我靠,为啥这个 G 3000+,赛事思考 5 分钟想出正解,30 min 没有调出来,(可能比较容易写挂),就是我们考虑把式子变形一下:

\[Y_i \ge A_j \times X_i + B_j \]

\[-B_j \ge A_j \times X_i - Y_i \]

那么我们可以将数对 \((X_i,Y_i)\) 视为一次函数,\((A_j,B_j)\) 视作限制。
那么题目求的东西也可以转换为对于一些 \(x\) 和一些一次函数,我们要求出对于每一个 \(x\),求出 \(f_i(x)\) 的个数满足函数值小于等于某一个值。
如果直接暴力的话那复杂度就是 \(x\) 的个数 \(\times\) 函数的个数,即:\(O(qn)\)。
我们考虑优化。

就是考虑对于一次函数来排序,然后二分
如果直接排序那就是负优化了。

我们可以这么做:
先对所有限制的 \(x\) 值进行排序。然后把每一对一次函数的交点处理出来,存进 vector,然后对于交点也按照 \(x\) 值排序。
于是我们可以类似扫描线,将限制的 \(x\) 从小到大来遍历

那么我们可以对于每一对一次函数求出交点,交点就相当于这两个一次函数需要类似于排序中的交换。但是直接交换似乎有问题,我们可以暴力将那些需要交换的一次函数取出来。然后暴力排序,在填入它们本来的位置即可。。(似乎非常暴力)。
这样我们就可以做到快速对于一次函数排序了。。

然后直接二分就做完了。
时间复杂度:\(O(n^2\log(n^2)+q\log(n))\)。

最后的最后,思考一下为什么最开始的式子需要变形。
因为如果不变形的话时间复杂度是 \(O(q^2\log(q^2)+n\log(q))\)。
变形就相当于将原题中的一次函数和限制交换了一下。
也就是让 \(n\) 和 \(q\) 交换了一下。所以才能保证通过。。
Difficulty: 3032,2400。
贴一下代码:

#include <bits/stdc++.h>
using namespace std;
#define rep(i,l,r) for (int i = (l); i <= (r); i++)
#define per(i,r,l) for (int i = (r); i >= (l); i--)
#define pb push_back
#define eb emplace_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
#define SZ(x) ((int)(x).size())
#define maxn(a, b) a = max(a, b)
#define minn(a, b) a = min(a, b)
typedef vector<int> VI;
typedef long long ll;
typedef pair<int,int> PII;
typedef double db;
const ll mod = (1ll<<31)-1;
ll rp(ll a,ll b) {ll res=1%mod;a%=mod; assert(b>=0); for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
ll gcd(ll a,ll b) { return b?gcd(b,a%b):a;}

const int N = 5043;
const int Q = 1e7+1;
int n, q, Ra;
pair<int,ll> a[Q];
int g[Q*3], pos[N];
ll Rb;
array<int,3> f[N];

ll calc(array<int, 3> t, int x) {
	return x * 1ll * t[0] + t[1];
}

db calc(const array<int, 3> &A, const array<int, 3> &B) {
	return (B[1] - A[1]) * 1.0 / (A[0] - B[0]);
}

int main() {
	scanf("%d", &n);
	rep(i,1,n) {
		scanf("%d%d", &f[i][0], &f[i][1]);
		f[i][1]*=-1;
		f[i][2]=i;
	}
	scanf("%d", &q);
	scanf("%d%d%lld", &g[0], &Ra, &Rb);
	rep(i,0,q*3) {
		g[i + 1] = (48271ll * g[i]) % mod;
	}
	rep(i,1,q) {
		a[i].fi = -Ra + (g[3*i-2]%(2ll*Ra+1));
		a[i].se = -Rb + ((g[3*i-1]*mod+g[3*i]) % (2 * Rb + 1));
		a[i].se*=-1;
	}
	sort(a + 1, a + 1 + q);
	rep(i,1,n) pos[f[i][2]] = i;
	vector<pair<db,pair<int,int>>> st;
	rep(i,1,n) {
		rep(j,i+1,n) if (f[i][0] != f[j][0]) {
			st.push_back({calc(f[i], f[j]), mp(f[i][2], f[j][2])});
		}
	}
	sort(all(st));
	ll ans = 0;
	int p = 0;
	rep(i,1,q) {
		set<int> pst;
		while (p < SZ(st) && st[p].fi < a[i].fi) {
			pst.insert(pos[st[p].se.fi]);
			pst.insert(pos[st[p].se.se]);
			p++;
		}
		if (i == 1) rep(j,1,n) pst.insert(j);
		vector<array<int,3>> vst;
		for (auto tp : pst) vst.pb(f[tp]);
		sort(all(vst), [&](const array<int, 3> &A, const array<int, 3> &B) {
			return calc(A, a[i].fi) > calc(B, a[i].fi);
		});
		assert(SZ(vst) == SZ(pst));
		for (auto tp : pst) {
			f[tp] = vst.back();
			vst.pop_back();
			pos[f[tp][2]] = tp;
		}
		int l = 1, r = n, res=0;
		while (l <= r) {
			int mid = l + r >> 1;
			if (calc(f[mid], a[i].fi) <= a[i].se) {
				res=mid;
				l=mid+1;
			} else r=mid-1;
		}
		ans+=res;
	}
	printf("%lld\n", ans);
	return 0;
}

标签:AtCoder,Beginner,int,rep,一次函数,344,fi,ll,define
From: https://www.cnblogs.com/weirdoX/p/18063616

相关文章

  • abc344_D - String Bags 题解
    一个月没有碰oi,感觉水平已经退化到负的了。来复健一下。D-StringBagslink题意:给你\(n\)组字符串组,按\(1\)~\(n\)的顺序,对于每组字符串组,可从中至多选一个字符串。求能否用所选串按顺序拼接成指定串,以及选取字符串的最小个数。然后读完题发现是个\(01\)背包;对于第......
  • AT_abc344_e 题解
    本文同步发表于洛谷。赌狗天天输的一集。赛时各种【数据删除】原因导致没做出来。大意给你一个长度为\(N\)的序列\(A=(A_1,\ldots,A_N)\)。保证\(A\)中的元素是不同的。你要处理\(Q\)个操作。每个操作是以下两种类型之一:1xy:在\(A\)中元素\(x\)后面紧接着插入......
  • AtCoder Beginner Contest 344
    基本情况ABCE秒了,D小细节处理出错(太久没写dp)+4。D-StringBagshttps://atcoder.jp/contests/abc344/tasks/abc344_d分组背包,但是字符串的细节要注意signedmain(){intn;std::stringT,str[110][15];intF[110][110],a[110];std::cin>>T>>n;......
  • AT_abc344_d 题解
    赌狗天天输的一集。大意你最开始有一个空字符串\(S\)。你还有编号为\(1,2,\dots,N\)的袋子,每个袋子都包含一些字符串。袋子\(i\)包含\(A_i\)个字符串\(S_{i,1},S_{i,2},\dots,S_{i,A_i}\)。对\(i=1,2,\dots,N\)重复以下步骤仅一次(这里原题没有讲清楚):......
  • AtCoder Regular Contest 171
    Preface小补一场ARC,D还是很有意思的但想了半天不会,鉴定为纯纯的彩笔A-NoAttacking考虑怎么放rook能使得留下来能放pawn的格子数量最多,手玩一下会发现先按照\((2,2),(4,4),(6,6),\cdots\)的顺序放,放满后再接着放\((1,1),(3,3),(5,5),\cdots\)是最优的手玩一下可以得出在放......
  • AtCoder Beginner Contest 343
    A-WrongAnswer(abc343A)题目大意给定\(a,b\),输出\(c\),使得\(a+b\neqc\)解题思路从\(0\)开始枚举\(c\)的取值即可。神奇的代码#include<bits/stdc++.h>usingnamespacestd;usingLL=longlong;intmain(void){ios::sync_with_stdio(false);cin.......
  • AtCoder Beginner Contest 321
    \[\large\text{Round12:AtCoderBeginnerContest321}\]一言:只要你在,我便无所不能。——进击的巨人感觉只有最后一道题有点意思,其他的就是时间问题,但是速度还是不够快,思维要跟上啊。有意思的是,周考考了回退背包,这里居然又来一次。。\(\text{G:ElectricCircuit}......
  • AtCoder Regular Contest 171
    \[\large\text{Round13:AtCoderRegularContest171}\]一言:我并不是要失去自由,而是要去收获那无可替代的不自由。——SSSS.电光机王几年没写了,但是我们仍然要捡回来!没啥好写的,T1,T2能力范围之内,T3不会,T4感觉很好,但是没做出来。\(\text{D:RollingHash}\)这题无论......
  • AtCoder Beginner Contest 298
    \[\large\text{Round5:AtCoderBeginnerContest298(VP)}\]一言:成一事者,是失之不渝的愚者;毁一事者,是停滞不前的贤者。——不正经的魔法讲师\(\text{Ex:SumofMinofLength}\)这次比赛总体难度不是很大,可能也是我第一次自己独立做出\(\text{Ex}\)。(虽然不是场切......
  • AtCoder Beginner Contest 315
    \[\large\text{Round6:AtCoderBeginnerContest315}\]一言:愿悲、爱恋、你和宇宙以及那颗星辰,能够永远拥抱我们。——THEBEYOND-機動戦士ガンダム40周年纪念曲这场打的一般,主要还是一开始网卡爆了把心态弄得很不好,一定程度上影响了发挥。\(\text{G:Ai+Bj+Ck......