ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

[Note] POI 板刷寄录 II

2022-08-26 08:32:15  阅读:182  来源: 互联网

标签:frd 板刷 di Note int GC 寄录 hd define


来点大紫大黑

[POI2013]LUK-Triumphal arch

A 的窝火。显然是二分,树形 dp check 一下即可。

这边证伪一下一种贪心 check:

首先我们从根节点 \(1\) 开始 dfs 全树。

同时记录一个变量 \(less\)。

如果当前的 $k 和 \(less\) 的和比儿子的数量少,肯定不行。

否则就 \(less\leftarrow less-\texttt{当前节点儿子数量}+k\),然后去判断儿子是不是都合法。


这种做法为什么是错的呢?

这种贪心写法错误在于你假装把剩余涂成黑点的机会滞后了,但是事实上在现实中并没有滞后,就是你必须在那一轮就涂下。

这样就会出现这样一个问题:如果有两棵的子树都通过利用 剩余涂成黑点的机会 滞后,但事实上纵观全局不一定能达成这样的效果,因为事实上你两棵子树都需要利用这个机会,但是你却在贪心过程中只让一颗子树利用这样的机会,所以是谬误的。

#include <bits/stdc++.h>
#define GC c=getchar()
#define IG isdigit(c)
#define int long long
#define rep(i,l,r) for(int i(l),_##i(r);i<=_##i;++i)
#define per(i,r,l) for(int i(r),_##i(l);i>=_##i;--i)
#define Go(i,hd,v) for(int i(hd),v;v=to[i],i;i=nxt[i])
template<class T=int>T frd(T x=0,char GC,bool f=1)
{
	for(;!IG;GC)f=c!='-';for(;IG;GC)x=x*10+(c^48);return f?x:-x;
}
using namespace std;
const int N(3e5+5);
int n,hd[N+5],to[N*2+5],nxt[N*2+5],deg[N+5],cntE,f[N+5];
inline void add(int u,int v){nxt[++cntE]=hd[u],hd[u]=cntE,to[cntE]=v,++deg[u];}
inline void Add(int u,int v){add(u,v),add(v,u);}
int dfs(int u,int sum,int fa)
{
	f[u]=deg[u]-sum;
	Go(i,hd[u],v) if(v!=fa) f[u]+=max(dfs(v,sum,u),0ll);
	return f[u];
}
signed main()
{
	n=frd();
	rep(i,2,n)Add(frd(),frd()),--deg[i];
	int L(0),R(n);
	while(L<R)
	{
		int mid(L+R>>1);
		dfs(1,mid,0)<=0?R=mid:L=mid+1;
	}
	printf("%lld\n",L);
	return 0;
}

[POI2015] KUR

这种计数很罕见。

我们直接去找有多少个起始位置符合条件。

显然当一个起始位置 \(start\) 符合条件,以 \(s_i = 0\) 为例必有

对于任意一个 \(i\in [1,m]\) 都有 \(a(start-1+i)+b \mod n < p\)。

为了方便我们 \(start\leftarrow start-1\)。

所以就是 \(a*start+(a*i+b) \mod n < p\)。

然后发现对于任意的一个 \(a*start\) 都有唯一确定的 \(start\) 与之对应(因为 \((a,n)=1\))。

而 \(a*start\) 的解集是连续的(可能不太必要的限定:在 \(\mod n\) 的情况下)。那么只要一个点被覆盖了 \(m\) 次即可。

但是,坑点是 \(q\in [n-m+1,n-1]\) 时是不合法的!!!

最后直接去除这种不合法情况即可。。

#include <bits/stdc++.h>
#define GC c=getchar()
#define IG isdigit(c)
#define rep(i,l,r) for(int i(l),_##i(r);i<=_##i;++i)
#define per(i,r,l) for(int i(r),_##i(l);i>=_##i;--i)
#define Go(i,hd,v) for(int i(hd),v;v=to[i],i;i=nxt[i])
template<class T=int>T frd(T x=0,char GC,bool f=1)
{
	for(;!IG;GC)f=c!='-';for(;IG;GC)x=x*10+(c^48);return f?x:-x;
}
using namespace std;
const int N(1e6+5);
int n,a,b,p,m,di[N*2+5],cntd,l[N+5],r[N+5],del[N+5],d[N*2+5],ans;
char s[N+5];
inline int ask(int x) {return lower_bound(di+1,di+1+cntd,x)-di;}
signed main()
{
	n=frd(),a=frd(),b=frd(),p=frd(),m=frd();
	scanf("%s",s+1);
	rep(i,1,m)  
	{
		int t((1ll*a*i+b)%n);
		if(s[i]^48) l[i]=p-t-1,r[i]=n-1-t;
		else l[i]=n-t-1,r[i]=p-1-t;
		if(l[i]<0)l[i]+=n;if(r[i]<0)r[i]+=n;
		di[++cntd]=l[i],di[++cntd]=r[i];
	}
	di[0]=-1,di[++cntd]=0,di[++cntd]=n-1;
	rep(i,n-m+1,n-1) del[n-i]=1ll*a*i%n;
	sort(di+1,di+1+cntd),sort(del+1,del+m);
	cntd=unique(di+1,di+1+cntd)-(di+1);
	rep(i,1,m)
	{
		l[i]=ask(l[i]),r[i]=ask(r[i]);
		--d[l[i]],++d[r[i]],l[i]>r[i]&&(++d[cntd]);
	}
	int npos(m-1);
	per(i,cntd,1)
	{
		d[i]+=d[i+1];int cnt(0);
		while(npos&&del[npos]>di[i-1]) --npos,++cnt;
		if(d[i]==m) ans+=di[i]-di[i-1]-cnt;
	}
	printf("%d\n",ans);
	return 0;
}

another

#include <bits/stdc++.h>
#define GC c=getchar()
#define IG isdigit(c)
#define rep(i,l,r) for(int i(l),_##i(r);i<=_##i;++i)
#define per(i,r,l) for(int i(r),_##i(l);i>=_##i;--i)
#define Go(i,hd,v) for(int i(hd),v;v=to[i],i;i=nxt[i])
template<class T=int>T frd(T x=0,char GC,bool f=1)
{
	for(;!IG;GC)f=c!='-';for(;IG;GC)x=x*10+(c^48);return f?x:-x;
}
using namespace std;
const int N(1e6+5);
int n,a,b,p,m,di[N*3+5],cntd,l[N+5],r[N+5],del[N+5],d[N*3+5],cntp,ans;
char s[N+5];
inline int ask(int x) {return lower_bound(di+1,di+1+cntd,x)-di;}
signed main()
{
	n=frd(),a=frd(),b=frd(),p=frd(),m=frd();
	scanf("%s",s+1);
	rep(i,1,m)  
	{
		int t((1ll*a*i+b)%n);
		if(s[i]^48) l[i]=p-t,r[i]=n-t;
		else l[i]=n-t,r[i]=p-t; 
		if(l[i]<0)l[i]+=n;if(r[i]<0)r[i]+=n; 
		di[++cntd]=l[i],di[++cntd]=r[i];
	}
	di[++cntd]=0,di[++cntd]=n;
	rep(i,n-m+1,n-1) del[n-i]=1ll*a*i%n;
	sort(di+1,di+1+cntd),sort(del+1,del+m);
	cntd=unique(di+1,di+1+cntd)-(di+1);
	rep(i,1,m)
	{
		l[i]=ask(l[i]),r[i]=ask(r[i]);
		++d[l[i]],--d[r[i]];
		if(l[i]>=r[i]) ++d[1];
	}
	int npos(1);
	rep(i,1,cntd-1)
	{
		d[i]+=d[i-1];int cnt(0);
		while(npos<m&&del[npos]<di[i+1])++npos,++cnt;
		if(d[i]==m) ans+=di[i+1]-di[i]-cnt;
	}
	printf("%d\n",ans);
	return 0;
}

标签:frd,板刷,di,Note,int,GC,寄录,hd,define
来源: https://www.cnblogs.com/1l2u3o/p/16626366.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有