在知乎上听zzx大佬说AGC练智商...于是试了一下

 

A.Range Product

给$a$,$b$,求$\prod^{b}_{i=a}i$是正数,负数还是$0$

。。。不写了

 

B.Box and Ball

有$n$个盒子,每个里面有一些小球,在$1$号盒子里有一个红球,现在给你若干次移动操作

每次移动是“从$x$中随机抽出一个球中放到$y$中”

最后询问有多少个盒子有可能有红球

。。。sb题吧,不写了口胡一下

发现一个盒子只要“有可能”被放过红球且未被拿光,就是“有可能”有红球,模拟即可

官方题解说的很好,考虑$1$号盒子里有一盒红墨水,其它盒子里有清水,每次移动操作可看做从$x$取出一杯溶液灌到$y$里

 

C.Knot Puzzle

有$n$个长度为$a_1,a_2,...,a_n$的绳子,第$i$个和第$i + 1$个绳子($1 \leq i \leq (n -1)$)通过打结连接起来

每次你可以选取一段还打着节的,且长度大于等于$L$的绳子,解开一个节

求最后能不能解开这$n-1$个节,如果可以输出操作序列

。。。sb题

首先 因为最后所有节都要被打开,我们需要连续的两个绳子加起来大于等于$L$,没有直接就是Impossible

找到了这两个,考虑构造

因为他俩就已经大于等于$L$了,我们可以先从左到右把左边一个一个拆下来

这样每一步都大于等于$L$

然后从右到左拆右边

最后拆他俩就可以啦

 

D.Stamp Rally

给一个$n$个点$m$条边的无向图,$q$组询问

每次给出$x$,$y$,$z$表示一个人从$x$出发,一个人从$y$出发,同时走

总共经过$z$个不同的点,要经过的编号最大的边编号最小是多少

n,m,q 1e5

#include<bits/stdc++.h>
#define LL long long
using namespace std;
inline int read()
{
    int x = 0,f = 1;char ch = getchar();
    for(;!isdigit(ch);ch = getchar())if(ch == '-')f = -f;
    for(;isdigit(ch);ch = getchar())x = 10 * x + ch - '0';
    return x * f;
}
const int maxn = 1e5 + 10;
int n,m,q;
struct EDG{int u,v;}es[maxn];
stack<EDG> s;
struct Ques
{
    int u,v,z,id;
}qs[maxn],ts[maxn];
int ans[maxn];
int fa[maxn],size[maxn];
inline int find(int x){return x == fa[x] ? x : find(fa[x]);}
inline void divide(int l,int r,int ql,int qr)
{
    if(l == r)
    {
        for(int i=ql;i<=qr;i++)ans[qs[i].id] = l;
        int fx = find(es[l].u),fy = find(es[l].v);
        if(size[fx] > size[fy])swap(fx,fy);if(fx != fy)fa[fx] = fy,size[fy] += size[fx];
        return;
    }
    int mid = (l + r) >> 1;
    for(int i=l;i<=mid;i++)
    {
        int fx = find(es[i].u),fy = find(es[i].v);
        if(size[fx] > size[fy])swap(fx,fy);if(fx != fy)fa[fx] = fy,size[fy] += size[fx],s.push((EDG){fx,fy});
    }
    int cnt1 = ql - 1,cnt2 = 0;
    int tot;
    for(int i=ql;i<=qr;i++)
    {
        int fx = find(qs[i].u),fy = find(qs[i].v);
        if(fx == fy)tot = size[fx];
        else tot = size[fx] + size[fy];
        if(tot >= qs[i].z)qs[++cnt1] = qs[i];
        else ts[++cnt2] = qs[i];
    }
    for(int i=1;i<=cnt2;i++)qs[cnt1 + i] = ts[i];
    while(!s.empty())
    {
        EDG h = s.top();s.pop();
        fa[h.u] = h.u;size[h.v] -= size[h.u];
    }
    divide(l,mid,ql,cnt1);divide(mid + 1,r,cnt1 + 1,qr);
}
int main()
{
    n = read(),m = read();
    for(int i=1;i<=m;i++){es[i].u = read(),es[i].v = read();}
    for(int i=1;i<=n;i++)fa[i] = i,size[i] = 1;
    q = read();
    for(int i=1;i<=q;i++)
    {
        qs[i].u = read(),qs[i].v = read(),qs[i].z = read();
        qs[i].id = i;
    }
    divide(1,m,1,q);
    for(int i=1;i<=q;i++)
        printf("%d\n",ans[i]);
}
View Code

相关文章:

  • 2022-12-23
  • 2021-08-28
  • 2021-09-27
  • 2021-05-17
  • 2021-11-16
  • 2022-01-12
  • 2021-09-22
  • 2022-01-27
猜你喜欢
  • 2021-07-09
  • 2021-08-08
  • 2021-04-21
  • 2021-08-05
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
相关资源
相似解决方案