「2019-8-11提高模拟赛」女装盛宴 (flag)

传送门

Solution?

基环树+倍增+双指针

第一次因为#define int long long而玄学RE

为什么标程都不用开\(long long\)啊

Code?

/*玄学RE 看来又是define ll long long 也有bug*/
#include<bits/stdc++.h>
#define ll long long
#define double
#define dbg1(x) cerr<<#x<<"="<<(x)<<" "
#define dbg2(x) cerr<<#x<<"="<<(x)<<"\n"
#define dbg3(x) cerr<<#x<<"\n"
using namespace std;
#define reg register
#define Z(x) memset(x,0,sizeof x)
inline ll read()
{
    ll x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
    return x*f;
}
const int MN=2e5+5;
ll n,m,a[MN],b[MN];bool mk[MN];
std::vector<int> G[MN];

ll len,c[MN<<1],la[MN];bool vis[MN];
void getcir(int x)
{
    len=0;int y;
    for(;;la[y]=x,vis[y]=1,x=y)
    {
        y=a[x];
        if(vis[y])
        {
            for(c[++len]=y;x^y;x=la[x])c[++len]=x;
            return;
        }
    }
}

ll d[MN],ans;
void dfs(int x,int fa,int no=0)
{
    int i;mk[x]=1;
    for(i=G[x].size()-1;~i;--i)if((G[x][i]^fa)&&(G[x][i]^no))
    {
        dfs(G[x][i],x);
        if(d[G[x][i]]+b[G[x][i]]>m) ++ans;
        else d[x]=max(d[x],d[G[x][i]]+b[G[x][i]]);
    }
}

ll f[20][MN],q[MN<<1],l,r,s[MN<<1];
void Push(int i){for(;r>=l&&d[c[q[r]]]-s[q[r]]<=d[c[i]]-s[i];--r);q[++r]=i;}
ll cal(ll x,ll y)
{
    ll _=len,tmp=0;
    for(int i=y;~i;--i)
        if(f[i][x]<_)tmp+=1<<i,_-=f[i][x],x=(x+f[i][x]-1)%len+1;
    return tmp+1;
}

void solve(int O)
{
    reg int i,j;
    len=0;getcir(O);
    for(i=1;i<=len;++i)dfs(c[i],0,c[i%len+1]);
    reverse(c+1,c+len+1);
    for(i=1;i<=len;++i)c[i+len]=c[i];
    for(i=2;i<=len*2;++i)s[i]=s[i-1]+b[c[i-1]];

    for(q[l=r=1]=i=j=1;i<=len;++i)
    {
        for(;r>=l&&q[l]<i;++l);if(r<l)q[++r]=++j;
        for(;j<i+len&&s[j]-s[q[l]]+d[c[q[l]]]<=m;++j,Push(j));
        if(j==i+len){++ans;return;}f[0][i]=j-i;
    }
    ll Add=n,fl=0;
    for(i=1;i<20;++i)
    {
        for(j=1;j<=len;++j)
        {
            f[i][j]=f[i-1][j]+f[i-1][(j+f[i-1][j]-1)%len+1];
            if(f[i][j]>=len-1) Add=min(Add,cal(j,i));
        }
        if(Add^n){ans+=Add;return;}
    }
}

int main()
{
#ifndef LOCAL
    freopen("flag.in","r",stdin);
    freopen("flag.out","w",stdout);
#endif
    int Case=read();
    while(Case--)
    {
        Z(d);ans=0;Z(vis);Z(mk);
        n=read(),m=read();
        reg int i;
        for(i=1;i<=n;++i) G[i].clear();
        for(i=1;i<=n;++i)
            a[i]=read(),b[i]=read(),G[a[i]].push_back(i);
        for(i=1;i<=n;++i)if(!mk[i])solve(i);
        printf("%lld\n",ans);
    }
    return 0;
}


Blog来自PaperCloud,未经允许,请勿转载,TKS!

原文地址:https://www.cnblogs.com/PaperCloud/p/11337066.html

时间: 2024-08-30 18:22:31

「2019-8-11提高模拟赛」女装盛宴 (flag)的相关文章

2017.6.11 校内模拟赛

题面及数据及std(有本人的也有原来的) :2017.6.11 校内模拟赛 T1 自己在纸上模拟一下后就会发现 可以用栈来搞一搞事情 受了上次zsq 讲的双栈排序的启发.. 具体就是将原盘子大小copy一下排个序 用两个指针维护两个数组(原数据 和 排序后的数据), 即分为1数据和2数组 将小于1指针指向的数据的2数组中的数据全部压入栈中 后进行消除, 将栈栈顶元素与当前1数组中的1指针指向的元素进行比较 相同则消除 后重复过程 直至指针超过N 后判断一下是否两个指针都超过了N... #incl

11.27 模拟赛

并没有人做的模拟赛... 出题人hx,,, T1:就是上一道矩阵乘法 数学题 T2: 一个数列中 一个区间满足,存在一个k(L <= k <= R),并且对于任意的i (L <= i <= R),ai都能被ak整除 这样的一个特殊区间 [L, R]价值为R - L 想知道序列中所有特殊区间的最大价值是多少,而有多少个这样的区间呢 这些区间又分别是哪些呢 输出每个区间的L 思路: 用两个ST表分别求一段区间的gcd和最小值 然后可以二分答案 check的时候枚举左端点,判断在这段区间

2017 9 11 noip模拟赛T2

#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int N=205; int map[N][N]; int d[N],tag[N],book[N],f[N]; int n,m; void work(int x) { memset(d,63,sizeof(d)); memset(book,0,sizeof(book)); memset(f,0,sizeof(

「CSP-S模拟赛」2019第一场

目录 T1 小奇取石子 题目 考场思路 正解 T2 「CCO 2017」专业网络 题目 考场思路 题解 T3 「ZJOI2017」线段树 题目 考场思路 正解 这场考试感觉很奇怪. \(T1.T2\) 都缺一个小特判. \(T3\) 打了个比暴力优的暴力 还是暴力,但是不知道为什么 \(WA\) 穿了. 考试的时候还玩扫雷... 其实,菜是原罪啊... ___ T1 小奇取石子 题目 点这里 考场思路 刚开始差点被自己坑了,开考 \(5min\) 就码出了一个可以惨痛爆零的 \(01\) 背包.

「CSP-S模拟赛」2019第二场

目录 T1 Jam的计数法 题目 考场思路(正解) T2 「TJOI / HEOI2016」排序 题目 考场思路(假正解) 正解 T3 「THUWC 2017」随机二分图 题目 考场思路 正解 这场考试的数据感觉很水. \(T1\) 签到不解释,\(T2\) 期望 \(50pts\) 结果有 \(100pts\),\(T3\) 一如既往地不可做... ___ T1 Jam的计数法 题目 点这里 考场思路(正解) 其实没有什么好说的,找找规律即可,看看代码吧. #include<cstdio>

2019.11.4模拟赛

T1 奇因数之和 定义\(F(n)\)为\(n\)的最大奇因数,例如\(F(1) = 1\),\(F(6) = 3\),\(F(12) = 3\). 输入\(m\),求\(\sum\limits_{i = 1}^{m}F(i)\). \(m \leq 10^{100}\) 分析一下我们发现,如果\(i\)是偶数,\(F(i) = F(i / 2)\),这样的话就可以分治求了. 这题难度在高精,谁考场上写大高精啊 r = open('sigma.in','r') w = open('sigma.o

11.4 模拟赛

终于AK了,虽然第三题主要是搞月想出来的 T1: n个1*1的小方块,把这些小方块拼成一个图形,使这个图形周长最小 思路: 枚举拼成长方形的长为i,宽为n/i 可得面积 (i+n/i+(bool)(n%i))*2 1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cstdlib> 5 #include<cmath> 6 #include<cstr

2017/11/3模拟赛

块(block)[问题描述]拼图达人小 C 手里有 n 个 1*1 的正方形方块, 他希望把这些方块拼在一起, 使得拼出的图形周长最小, 要求方块不能重叠. 擅长拼图的小 C 一下就求出了这个周长, 顺便他想考考你会不会求.[输入格式]多组数据, 第一行一个正整数 T, 表示数据组数.接下来 T 行, 每行一个正整数 n, 表示方块数.[输出格式]输出 T 行, 每行一个正整数, 表示答案.[样例输入]3 4 1122[样例输出]81420[数据范围]对于 20%的数据, n<=20:对于 40

2017/11/1模拟赛

磁星(magnet)[题目描述]在 B 城呆惯了的小 H 决定去外太空溜达一圈.人类现已发现并开发的星球(包括小 H 所在的星球)有 n 个,并且在这 n 个星球之中,人们发现了 m 对两个星球的关系.关系"xy"表示的是星球 x 对星球 y 有 1 一个单位的引导力,由于引导力还具有传递性,如果星球 x 对星球 y 能有恰好 a 个单位的引导力,星球y 对星球 z 能有恰好 b 个单位的引导力,那么星球 x 对星球 z 就能有恰好 a+b 个单位的引导力. 换言之,星球 x 对星球