zoukankan      html  css  js  c++  java
  • 「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)<<"
    "
    #define dbg3(x) cerr<<#x<<"
    "
    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
    ",ans);
    	}
    	return 0;
    }
    


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

  • 相关阅读:
    ubuntu 17.10 安装后的应用软件安装
    设计模式之组合模式(Composite)
    设计模式之桥接模式(Bridge)
    设计模式之外观模式(Facade)
    设计模式之代理模式(Proxy)
    Linux设备驱动剖析之IIC(三)
    Linux设备驱动剖析之IIC(二)
    Linux设备驱动剖析之IIC(一)
    Linux设备驱动剖析之SPI(四)
    Linux设备驱动剖析之SPI(三)
  • 原文地址:https://www.cnblogs.com/PaperCloud/p/11337066.html
Copyright © 2011-2022 走看看