Loading

noip模拟48

A. Lighthouse

无脑状压+无脑容斥.

A_code
#include<bits/stdc++.h>
using namespace std;
namespace BSS {
	#define ll long long int
	#define ull unsigned ll
	#define re register int 
	#define lf double
	#define lbt(x) (x&(-x))
	#define mp(x,y) make_pair(x,y)
	#define lb lower_bound 
	#define ub upper_bound
	#define File(x,y) freopen(#x,"r",stdin),freopen(#y,"w",stdout)
	#define Fill(x,y) memset(x,y,sizeof x)
	#define Copy(x,y) memset(x,y,sizeof x)
	inline int read() {
		int ss=0; bool cit=1; char ch;
		while(!isdigit(ch=getchar())) if(ch=='-') cit=0; 
		while(isdigit(ch)) ss=(ss<<3)+(ss<<1)+(ch^48),ch=getchar();
		return cit?ss:-ss;
	}
} using namespace BSS;

const ll N=21,M=101,NM=1e7+31;
const ll mod=1e9+7;

ll m,n,U,cnt,ans,res,ts;
ll f[1<<N],g[1<<N],lsh[M],add[NM],jc[NM],flg[M],vis[M];
ll d[M],ban[1<<N];;
struct I { ll u,v; } e[M];
inline ll ksm(ll a,ll b,ll c){
	ll temp=1; a%=c;
	while(b){
		if(b&1) temp=(temp*a)%c;
		a=(a*a)%c,b>>=1;
	}
	return temp%c;
}
signed main(){
	n=read(),m=read(),U=(1<<m)-1;
	ll u,v,flag;
	for(re i=1;i<=m;++i)
		lsh[++cnt]=e[i].u=read(),
		lsh[++cnt]=e[i].v=read();
	sort(lsh+1,lsh+1+cnt);
	cnt=unique(lsh+1,lsh+1+cnt)-lsh-1;
	for(re i=1;i<=m;++i)
		e[i].u=lb(lsh+1,lsh+1+cnt,e[i].u)-lsh,
		e[i].v=lb(lsh+1,lsh+1+cnt,e[i].v)-lsh;
	for(re i=0;i<=U;++i){
		u=i,g[i]=0;
		while(u) u-=lbt(u),g[i]++;
	}
	add[0]=1,jc[0]=1;
	for(re i=1;i<=n;++i) add[i]=(add[i-1]*2)%mod,jc[i]=(jc[i-1]*i)%mod;
	for(re i=1;i<=m;++i) d[e[i].u]++,d[e[i].v]++;
	for(re i=1;i<=cnt;++i){
		if(d[i]>=n-1) puts("0"),exit(0);
		d[i]=0;
	}
	for(re i=0;i<=U;++i){
		if(ban[i]) continue;
		u=0,flag=0;
		for(re j=1;j<=m;++j)
			if((i>>(j-1))&1){
				d[e[j].u]++,d[e[j].v]++;
			}
		for(re j=1;j<=cnt;++j) flag+=(d[j]>2),u+=(d[j]==1);
		for(re j=1;j<=cnt;++j) d[j]=0;
		if(g[i]==n) res=1;
		else{
			if(i and (!u)){
				ll temp=U xor i;
				for(ll S=temp;S;(--S)&=temp) ban[i|S]=1;
				continue;
			}
			if(flag) continue;
			u>>=1,res=jc[n-g[i]-1]*ksm(2,mod-2,mod)%mod*add[u]%mod;
		}
		if(g[i]&1) ans=(mod+ans-res)%mod;
		else ans=(ans+res)%mod;
	}
	printf("%lld\n",ans);
	exit(0);
}
/*
6 10
4 2
2 6
4 3
5 4
1 3
1 6
1 5
3 2
6 3
4 6
*/

B. Miner

推个性质答案就出来了..

B_code
#include<bits/stdc++.h>
using namespace std;
namespace BSS
{
	#define ll long long int
	#define ull unsigned ll 
	#define re register ll 
	#define lf double
	#define lb lower_bound 
	#define ub upper_bound 
	#define mp make_pair
	#define File(x,y) freopen(#x,"r",stdin),freopen(#y,"w",stdout)
	#define Fill(x,y) memset(x,y,sizeof x);
	#define Copy(x,y) memcpy(x,y,sizeof x);
	inline ll read()
	{
		ll ss=0; bool cit=1; char ch;
		while(!isdigit(ch=getchar())) if(ch=='-') cit=0;
		while(isdigit(ch)) ss=(ss<<3)+(ss<<1)+(ch^48),ch=getchar();
		return cit?ss:-ss;
	}
} using namespace BSS;

const ll N=3e5+21;

ll m,n,ts=1,cnt,tot,ans=-1;
ll d[N],fa[N],c[N],vis[N<<1],head[N],s[N],lft[N<<2];
vector<ll> vec[N];
pair<ll,ll> res[N<<2];
struct I { ll u,v,w,nxt; } e[N<<1];
inline void add(ll u,ll v,ll w){
	e[++ts].u=u,e[ts].v=v,e[ts].w=w,e[ts].nxt=head[u],
	head[u]=ts;
}
ll find(ll x){ return x==fa[x] ? x : fa[x]=find(fa[x]) ; }
inline void Oula(){
	stack<pair<ll,ll> > stk;  
	for(re i=1;i<=n;++i) 
		if(head[i]){
			stk.push(mp(vec[find(i)][0],0));
			break;
		}
	while(stk.size()){
		ll u=(stk.top()).first,i=head[u];
		while(i and vis[i]) i=e[i].nxt;
		if(i) stk.push(mp(e[i].v,e[i].w)),vis[i]=vis[i^1]=1,head[u]=e[i].nxt;
		else res[++tot]=stk.top(),stk.pop();
	}
}
signed main(){
	n=read(),m=read(); ll u,v,w;
	for(re i=1;i<=n;++i) fa[i]=i;
	for(re i=1;i<=m;++i)
		u=read(),v=read(),add(u,v,0),add(v,u,0),d[u]++,d[v]++,fa[find(u)]=find(v);
	for(ll i=1;i<=n;++i) if(d[i]&1) vec[find(i)].push_back(i);
	for(ll i=1;i<=n;++i){
		ans+=max(1,(int)vec[find(i)].size()>>1)*(!vis[find(i)])*(d[find(i)]>0),vis[find(i)]=1;
		if(vis[i] and vec[i].empty()) vec[i].push_back(i),vec[i].push_back(i);
	}
	ll st=1,lst=0;
	for(;st<=n;++st)
		if(vis[st] and head[st]){
			for(re j=2;j<vec[st].size();j++) lft[++cnt]=vec[st][j];
			lst=st; break; 
		}
	for(st++;st<=n;st++)
		if(vis[st] and head[st]){
			add(vec[lst][1],vec[st][0],1),add(vec[st][0],vec[lst][1],1);
			for(re j=2;j<vec[st].size();j++) lft[++cnt]=vec[st][j];
			lst=st;
		}
	for(re i=1;i<=cnt;i+=2) add(lft[i],lft[i+1],1),add(lft[i+1],lft[i],1);
	Fill(vis,0); Oula();
	printf("%lld\n",ans);
	printf("%lld\n",res[tot--].first);
	for(re i=tot;i>=1;i--) printf("%lld %lld\n",res[i].second,res[i].first);
	exit(0);
}

C. Lky Love Painting

二分 \(+\) 动态规划.

记录一下上一次从哪里转移的即可.

C_code
#include<bits/stdc++.h>
using namespace std;
namespace BSS {
	#define ll long long int
	#define ull unsigned ll
	#define re register int 
	#define lf double
	#define lbt(x) (x&(-x))
	#define mp(x,y) make_pair(x,y)
	#define lb lower_bound 
	#define ub upper_bound
	#define File(x,y) freopen(#x,"r",stdin),freopen(#y,"w",stdout)
	#define Fill(x,y) memset(x,y,sizeof x)
	#define Copy(x,y) memset(x,y,sizeof x)
	inline int read() {
		int ss=0; bool cit=1; char ch;
		while(!isdigit(ch=getchar())) if(ch=='-') cit=0; 
		while(isdigit(ch)) ss=(ss<<3)+(ss<<1)+(ch^48),ch=getchar();
		return cit?ss:-ss;
	}
} using namespace BSS;

const ll N=1e5+51,M=107;

ll m,n;
ll val[4][N];
ll f[N],nxt1[N],nxt2[N],nxt3[N],pre1[N],pre2[N],pre3[N];
inline bool check(ll lmt){
	for(re i=0;i<=n+1;++i) nxt1[i]=0,nxt2[i]=0,nxt3[i]=0;
	for(re i=1;i<=n;++i){
		nxt1[i]=nxt1[i-1],nxt2[i]=nxt2[i-1],nxt3[i]=nxt3[i-1];
		while(pre1[i]-pre1[nxt1[i]]>lmt) nxt1[i]++;
		while(pre2[i]-pre2[nxt2[i]]>lmt) nxt2[i]++;
		while(pre3[i]-pre3[nxt3[i]]>lmt) nxt3[i]++;
		f[i]=m+1;
	}
//	cout<<"Limit:"<<lmt<<'\n';
//	for(re i=1;i<=n;++i) cout<<nxt1[i]<<' '<<nxt2[i]<<" "<<nxt3[i]<<'\n';
	ll temp,p1,p2;
	f[0]=0;
	for(re i=1;i<=n;++i){
		temp=0,p1=i,p2=i;
		while(temp<=m and (p1 or p2)){
			if(p1>p2) p1=nxt1[p1];
			else p2=nxt2[p2];
//			cout<<"p1:"<<p1<<"   p2:"<<p2<<'\n';
			temp++,
			f[i]=min(f[i],f[max(p1,p2)]+temp);
		}
		f[i]=min(f[i],f[nxt3[i]]+1);
		if(f[i]>m) return 0;
	}
	return 1;
}
signed main(){
	n=read(),m=read();
	ll le=0,ri=0,mid,res;
	for(re i=1;i<=n;++i) 
		ri+=val[1][i]=read(),le=max(le,val[1][i]),val[3][i]+=val[1][i];
	for(re i=1;i<=n;++i)
		ri+=val[2][i]=read(),le=max(le,val[2][i]),val[3][i]+=val[2][i],
		pre1[i]=pre1[i-1]+val[1][i],pre2[i]=pre2[i-1]+val[2][i],pre3[i]=pre3[i-1]+val[3][i];
	res=ri;
	while(le<=ri){
		mid=(le+ri)>>1;
		if(check(mid)) res=mid,ri=mid-1;
		else le=mid+1;
//		cout<<"res:"<<res<<endl;
	}
	printf("%lld\n",res);
	exit(0);
}

D. Revive

posted @ 2021-09-10 15:56  AaMuXiiiiii  阅读(55)  评论(0)    收藏  举报