Loading

noip模拟63

A. 电压机制

题目可以迅速转化为:删掉一条边使得图变为一个二分图.

然而这并没有什么用..

另外可以发现我们必须删掉一条边,这条边满足是所有奇环的公共边,而且不能是偶环的边.

所以可以考虑差分实现.

A_code
#include<bits/stdc++.h>
using namespace std;
namespace BSS {
	#define ll long long int
	#define ull unsigned ll
	#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 Fill(x,y) memset(x,y,sizeof x)
	#define Copy(x,y) memcpy(x,y,sizeof x)
	#define File(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout)
	inline ll read() {
		ll res=0; bool cit=1; char ch;
		while(!isdigit(ch=getchar())) if(ch=='-') cit=0; 
		while(isdigit(ch)) res=(res<<3)+(res<<1)+(ch^48),ch=getchar();
		return cit?res:-res;
	}
} using namespace BSS;

const ll N=5e5+21;

ll m,n,ans,ts=1,cnt,alls;
ll head[N],odd[N],cf[N],dep[N];
struct I { ll u,v,nxt,vis; } e[N<<2];
inline void add(ll u,ll v){
	e[++ts].u=u,e[ts].v=v,e[ts].nxt=head[u],
	head[u]=ts;
}
void dfs(ll u,ll depth){
	dep[u]=depth;
	for(int i=head[u];i;i=e[i].nxt){
		if(e[i].vis) continue;
		e[i].vis=1,e[i^1].vis=1;
		if(dep[e[i].v]){
			ll len=dep[u]-dep[e[i].v]+1;
			if(len&1){
				odd[i]++,odd[i^1]++;
				cf[e[i].v]--; alls++;
			} 
			else{
				odd[i]--,odd[i^1]--;
				cf[e[i].v]++;
			}
			cf[u]+=odd[i];
		}
		else{
			dfs(e[i].v,depth+1);
			odd[i]+=cf[e[i].v],odd[i^1]+=cf[e[i].v];
			cf[u]+=cf[e[i].v];
		}
	}
}
signed main(){
	File(a);
	n=read(),m=read(); ll u,v;
	for(int i=1;i<=m;i++){
		u=read(),v=read();
		add(u,v),add(v,u);
	}
	dfs(1,1);
	for(int i=2;i<=ts;i+=2) ans+=(odd[i]==alls);
	printf("%lld\n",ans),exit(0);
}

B. 括号密码

从部分分或许能启发来一些想法.

首先考虑不嵌套不重叠,那么肯定是选择能对两个区间都有效的交换更优.

考虑嵌套不重叠,那么发现其实按左端点升序,右端点降序,然后无脑扫一遍,按照不重叠不嵌套的情况扫一遍即可,自己手玩发现很好写.

考虑重叠不嵌套,发现重叠部分必须是一个合法区间,于是拆开即可,回到不重叠不嵌套的情况.

考虑既重叠又嵌套,那么分别简化回到第一种情况即可,注意要先把重叠拆开,因为这样会很好做.

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

const int N=1e5+21;

char ch[N];
int m,n,ls,rs,ans,lks,rks,lens;
int val[N],pre[N],vis[N];
struct I { 
	int l,r,w; 
	I(){}
	I(int _l,int _r):l(_l),r(_r) {}
	inline friend bool operator == (I i,I j){
		return i.l==j.l and i.r==j.r;
	}
} p[N*20];
auto check=[](int x)->void{
	if((p[x].r-p[x].l+1)&1) puts("-1"),exit(0);
};
auto spart=[](int l1,int l2,int r2,int r1)->void{
	// cout<<l1<<' '<<l2<<' '<<r2<<' '<<r1<<endl;
	if(l1<l2) n++,p[n]=I(l1,l2-1),check(n);
	n++,p[n]=I(l2,r2),check(n);
	if(r2<r1) n++,p[n]=I(r2+1,r1),check(n);
};
signed main(){
	File(b);
	scanf("%s",ch+1),m=strlen(ch+1),n=read(); int l,r,w,mn;
	for(int i=1;i<=m;i++){
		(ch[i]=='(') ? (ls++,val[i]=1) : (rs++,val[i]=-1);
	}
	for(int i=1;i<=n;i++) p[i].l=read()+1;
	for(int i=1;i<=n;i++) p[i].r=read()+1,check(i);
	sort(p+1,p+1+n,[](I i,I j){ return i.l==j.l ? i.r>j.r : i.l<j.l; });
	n=unique(p+1,p+1+n)-p-1;
	for(int i=1,lmi=n;i<=lmi;i++){
		for(int j=1;j<=lmi;j++){
			if(p[j].l>p[i].l and p[j].l<p[i].r and p[i].r<p[j].r){
				spart(p[i].l,p[j].l,p[i].r,p[j].r);
			}
		}
	}
	// for(int i=1;i<=n;i++) cout<<p[i].l<<' '<<p[i].r<<endl;
	sort(p+1,p+1+n,[](I i,I j){ return i.l==j.l ? i.r>j.r : i.l<j.l; });
	n=unique(p+1,p+1+n)-p-1;
	for(int i=n;i;i--){
		w=0,mn=0;
		for(int j=p[i].l,lmj=p[i].r;j<=lmj;j++){
			if(vis[j]) continue;
			w+=val[j],mn=min(mn,w),lens++,vis[j]=1;
		}
		assert((w&1)==0);
		if(w>=0) lks+=abs(w>>1),ans+=abs(mn>>1);
		else rks+=abs(w>>1),ans+=abs(mn-w)>>1,ans+=abs(mn&1);
	}
	if((lens>>1)>ls or (lens>>1)>rs) puts("-1"),exit(0);
	printf("%d\n",ans+abs(max(lks,rks)));	
	exit(0);
}

C. 排列

D. B关系

posted @ 2021-09-28 19:53  AaMuXiiiiii  阅读(22)  评论(0编辑  收藏  举报