AtCoder Beginner Contest 294(D-G
创始人
2025-06-01 01:40:53

D - Bank (atcoder.jp)

        (1)题目大意

                给你N个id,以及Q个询问,1表示用未被用到的最小的一个id,2表示x这个id现在被用到了,3表示再喊已经被喊的最小的那个人的id。

         (2)解题思路

                用两个set模拟即可。

         (3)代码实现

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#define rep(i,z,n) for(int i = z;i <= n; i++)
#define per(i,n,z) for(int i = n;i >= z; i--)
#define PII pair
#define fi first
#define se second
#define vi vector
#define vl vector
#define pb push_back
#define sz(x) (int)x.size()
#define all(x) (x).begin(),(x).end()
using namespace std;
using ll = long long;
const int N = 2e5 + 10;
void solve()
{int n,m;cin >> n >> m;set  st,has;rep(i,1,n) st.insert(i);rep(i,1,m) {int op,x;cin >> op;if(op == 1) {int v = *st.begin();st.erase(st.begin());has.insert(v);}else if(op == 2) {cin >> x;has.erase(x);}else {cout << *has.begin() << endl;}}
}
int main()
{ios::sync_with_stdio(false);cin.tie(0),cout.tie(0);int T = 1;// cin >> T;while(T --) solve();return 0;
}

E - 2xN Grid (atcoder.jp)

        (1)题目大意

                给你一个2*L的矩阵,第一行有N1个小段,每一段是一个数,第二行有N2个小段,每一段也是一个数,问你有多少对A[1][j] = A[2][j]

         (2)解题思路

                类似于区间合并的思想,使用双指针,若当上下指针区间元素一样,则算这个区间的交集是多少,然后根据上下指针的右边界的大小移动指针即可。

         (3)代码实现

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#define rep(i,z,n) for(int i = z;i <= n; i++)
#define per(i,n,z) for(int i = n;i >= z; i--)
#define PII pair
#define fi first
#define se second
#define vi vector
#define vl vector
#define pb push_back
#define sz(x) (int)x.size()
#define all(x) (x).begin(),(x).end()
#define PLL pair
using namespace std;
using ll = long long;
const int N = 2e5 + 10;
struct Node {ll l,r;int v;
}a[N],b[N];
ll inter(ll l1,ll r1,ll l2,ll r2)
{return min(r1,r2) - max(l1,l2) + 1;
}
void solve()
{ll L,n,m;cin >> L >> n >> m;ll st = 1,x;int v;rep(i,1,n) {cin >> v >> x;a[i] = {st,st + x - 1,v};st += x;}st = 1;rep(i,1,m) {cin >> v >> x;b[i] = {st,st + x - 1,v};st += x;}int l1 = 1,l2 = 1;ll ans = 0;while(l1 <= n + 1 && l2 <= m + 1) {if(a[l1].v == b[l2].v) ans += inter(a[l1].l,a[l1].r,b[l2].l,b[l2].r);if(a[l1].r >= b[l2].r) l2 ++;else l1 ++;}cout << ans << endl;
}
int main()
{ios::sync_with_stdio(false);cin.tie(0),cout.tie(0);int T = 1;// cin >> T;while(T --) solve();return 0;
}

F - Sugar Water 2 (atcoder.jp)

        (1)题目大意

                两个人分别由N个瓶子和M个瓶子的糖水,设第一个人第i个瓶子由Ai克糖和Bi克水,第二个人第j个瓶子由Cj克糖和Dj克水,分别从两个人中取出一个瓶子,问你第k大糖分率是多少?

         (2)解题思路

                考虑k过大,因此考虑二分答案V

                式子可以写为\frac{xi + xj}{xi + yi + xj + yj} > V,若满足这个式子有大于V的个数有K个,那么此答案符合要求,把除法变乘法xi + xj > V(xi + yi + xj + yj),把i放一边j放一边变为(1-V)xi-Vyi>(V-1)xj+Vyj,把AB数组处理成左边式子,把CD数组处理成右边式子,排个序双指针扫一下看有多少个满足条件即可。

         (3)代码实现

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#define rep(i,z,n) for(int i = z;i <= n; i++)
#define per(i,n,z) for(int i = n;i >= z; i--)
#define PII pair
#define fi first
#define se second
#define vi vector
#define vl vector
#define pb push_back
#define sz(x) (int)x.size()
#define all(x) (x).begin(),(x).end()
using namespace std;
using ll = long long;
const double eps = 1e-14;
const int N = 2e5 + 10;
PII a[N],b[N];
long double A[N],B[N];
ll n,m,k;
bool check(long double V)
{rep(i,1,n) A[i] = (1 - V) * a[i].fi - V * a[i].se;rep(i,1,m) B[i] = (V - 1) * b[i].fi + V * b[i].se;sort(A + 1,A + 1 + n);sort(B + 1,B + 1 + m);ll cnt = 0,cur = 1;rep(i,1,n) {while(cur <= m && B[cur] <= A[i]) cur ++;cnt += cur - 1;}return cnt >= k;
}
void solve()
{cin >> n >> m >> k;cout << fixed << setprecision(15);rep(i,1,n) cin >> a[i].fi >> a[i].se;rep(i,1,m) cin >> b[i].fi >> b[i].se;long double l = 0,r = 1;while(r - l >= eps) {long double mid = (l + r) / 2;if(check(mid)) l = mid + eps;else r = mid - eps;}cout << l * 100 << endl;
}
int main()
{ios::sync_with_stdio(false);cin.tie(0),cout.tie(0);int T = 1;// cin >> T;while(T --) solve();return 0;
}

G - Distance Queries on a Tree (atcoder.jp)

        (1)题目大意

                给你一颗树有N个节点,有两种操作,第一种操作是把第i条边的权值修改为w,第二个操作是询问u到v的路径和。

         (2)解题思路

                预处理出dfs序,因为树上操作不好直接修改,因此转换成区间问题,又因为是边权和,我们可以按照dfs序把边权转换为点权处理,按照拆点的思路把树上每一个点分成入点和出点,若修改了第i条边的权值,相当于修改了第i条边的入点的和,然后在这个出点+1的位置减去修改的即可,因此可以考虑树状数组进行单点修改和区间查询。

                注意查询的时候我们是qry[1,in[u]] + qry[1,in[v]] - 2 *qry[1,lca(in[u],in[v]));查询的时候是直接查询第u节点之前的和和节点之前的和然后减去他们2倍lca的和,因为他们lca之前的全部都重复了,比如。

                

        查询4和5的和,要减去2倍2之前的和。

        (3)代码实现

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#define rep(i,z,n) for(int i = z;i <= n; i++)
#define per(i,n,z) for(int i = n;i >= z; i--)
#define PII pair
#define fi first
#define se second
#define vi vector
#define vl vector
#define pb push_back
#define sz(x) (int)x.size()
#define all(x) (x).begin(),(x).end()
using namespace std;
using ll = long long;
const int N = 2e5 + 10;
int siz[N],in[N],out[N],son[N],fa[N],top[N],dep[N],pid[N],tim;
int he[N];
struct Edge {int x,y;int v;
}e[N];
vector  G[N];
void dfs1(int u,int f)
{siz[u] = 1;in[u] = ++ tim;dep[u] = dep[f] + 1;fa[u] = f;for(auto x : G[u]) {if(x.fi == f) continue;dfs1(x.fi,u);pid[x.se] = x.fi;siz[u] += siz[x.fi];if(siz[x.fi] > siz[son[u]]) son[u] = x.fi;}out[u] = ++ tim;
}
void dfs2(int u,int f)
{top[u] = f;if(son[u]) dfs2(son[u],f);for(auto x : G[u]) {if(x.fi == fa[u] || x.fi == son[u]) continue;dfs2(x.fi,x.fi);}
}
int getLCA(int x,int y)
{while(top[x] != top[y]) {if(dep[top[x]] < dep[top[y]]) swap(x,y);x = fa[top[x]];}if(dep[x] > dep[y]) swap(x,y);return x;
}
struct Fenwick{ll tr[(N << 2) + 10];int n;Fenwick(int n = 0) {init(n);}void init(int n) {this->n = n;for(int i = 1;i <= n;++ i) {tr[i] = 0;}}int lowbit(int x) {return x & -x;}void add(int x,int v) {while(x <= n) {tr[x] += v;x += lowbit(x);}}ll qry(int x) {ll res = 0;while(x >= 1) {res += tr[x];x -= lowbit(x);}return res;}
};
void solve()
{int n,u,v;cin >> n;rep(i,1,n - 1) {int x,y,w;cin >> x >> y >> w;G[x].pb({y,i});G[y].pb({x,i});e[i] = {x,y,w};}dfs1(1,0);dfs2(1,0);Fenwick fen(n * 2);rep(i,1,n - 1) {int rp = pid[i];fen.add(in[rp],e[i].v);fen.add(out[rp] + 1,-e[i].v);}int q;cin >> q;while(q --) {int op,x,y;cin >> op >> x >> y;if(op == 1) {int rp = pid[x];fen.add(in[rp],y - e[x].v);fen.add(out[rp] + 1,e[x].v - y);e[x].v = y;}else {//询问x,yint pf = getLCA(x,y);cout << fen.qry(in[x]) + fen.qry(in[y]) - 2 * fen.qry(in[pf]) << endl;}}
}
int main()
{ios::sync_with_stdio(false);cin.tie(0),cout.tie(0);int T = 1;// cin >> T;while(T --) solve();return 0;
}

 

相关内容

热门资讯

cad打印线条粗细设置 cad... 004-线型(下)打印样式设置和线型文件使用一、线宽设置方法制图规范里边的线宽要求,我们已经定义好,...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
阿西吧是什么意思 阿西吧相当于... 即使你没有受到过任何外语培训,你也懂四国语言。汉语:你好英语:Shit韩语:阿西吧(아,씨발! )日...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...