首页 > 其他分享 >ABC340

ABC340

时间:2024-02-11 10:57:20浏览次数:33  
标签:frac 200005 int ed ABC340 mp return

\(\huge{C}\)
link

首先,考虑暴力,用一个堆,存所有数,每次拿出最大的数,拆开加入堆,计入答案,直到最大的\(\le1\),时间复杂度\(O(\text{不能过})\)。
考虑想求出\(n\),要什么。
求\(n\)一定是第一次把\(n\)拆成\(\lfloor{\frac{n}{2}}\rfloor\)和\(\lceil{\frac{n}{2}}\rceil\),答案加上\(n\),之后再继续拆\(\lfloor{\frac{n}{2}}\rfloor\)和\(\lceil{\frac{n}{2}}\rceil\),再继续拆……简单考虑一下即可得,\(n\)的答案就是\(n\)+\(\lfloor{\frac{n}{2}}\rfloor\)和\(\lceil{\frac{n}{2}}\rceil\)的答案。
这时,可以递归,加一个记忆化,时间复杂度\(O(\text{能过})\)。
特殊情况

  • \(n=2\)时,答案为\(2\)。
点击查看代码
#include<bits/stdc++.h>

#define int long long

using namespace std;

int n;
map<int,int> mp;

int dfs(int x){
	if(x == 2) return 2;
	if(x == 1) return 0;
	if(mp.find(x) != mp.end()) return mp[x];
	mp[x] = dfs(x/2)+dfs((x+1)/2)+x;
	return mp[x];
}

signed main(){
	
	cin >> n;
	
	cout << dfs(n);
	
	return 0;
	
} 

\(\huge{D}\)
link

每个点可以到\(i+1\)和\(x_i\),考虑\(i\)向\(i+1\)和\(x_i\)连边,跑\(Dijkstra\)即可。

点击查看代码
#include<bits/stdc++.h>

#define int long long
#define PII pair<int,int>

using namespace std;

int n;
int a[200005],b[200005],x[200005];
vector<pair<int,int> > ed[200005];
int f[200005];

void dijkstra(int s){
	priority_queue<PII,vector<PII>,greater<PII> > q;
	q.push({0,s});
	for(int i = 1;i <= n;++ i)
		f[i] = 1e15;
	f[s] = 0;
	while(!q.empty()){
		int t = q.top().first,x = q.top().second;
		q.pop();
		if(t > f[x]) continue;
		for(int i = 0;i < ed[x].size();++ i){
			int y = ed[x][i].first;
			int w = ed[x][i].second;
			if(f[y] > f[x]+w){
				f[y] = f[x]+w;
				q.push({f[y],y});
			}
		}
	}
}

signed main(){
	
	cin >> n;
	for(int i = 1;i < n;++ i){
		cin >> a[i] >> b[i] >> x[i];
		ed[i].push_back({i+1,a[i]});
		ed[i].push_back({x[i],b[i]});
	}
	
	dijkstra(1);
	
	cout << f[n];
	
	return 0;
	
}

\(\huge{E}\)
link

最开始我看到每个加1,于是考虑到了差分,可是差分无法随时找出\(a_{b_i}\),无法用。
于是,我们需要一个即能区间修改值,又能随时查询某个点的值得数据结构——线段树。
每次输入了\(b_i\)(后面用\(x\)),找出\(x\)的值

标签:frac,200005,int,ed,ABC340,mp,return
From: https://www.cnblogs.com/wmmdbk/p/18013210

相关文章

  • ABC340
    T1:ArithmeticProgression模拟代码实现a,b,d=map(int,input().split())foriinrange(a,b+1,d):print(i,end='')T2:Append模拟代码实现q=int(input())a=[]forqiinrange(q):type,x=map(int,input().split())iftype==1:......
  • AtCoder-abc340_f题解
    题意简述给定整数\(x,y\),询问是否存在整数\(a,b\),满足:\(-10^{18}\lea,b\le10^{18}\)。由\((0,0),(x,y),(a,b)\)三点构成的三角形面积为\(1\)。如果存在,输出任意一组;否则输出-1。思路先假设\(x,y,a,b\)都是正数。那么图大概是这样:此时红色三角形的面积就......
  • ABC340
    E我们可以知道每一个点在每一轮加多少,具体如下:假如现在操作的点的为\(k\)。那么所有的数都至少会加\(\dfrac{A_k}{n}\)。但是肯定有剩的,剩了\(A_k\modn\)。很明显,\(A_k\modn\)会分给接下来的\(A_k\modn\)个数。这样我们就可以知道每个点每轮加多少了。然后用线段......