• Educational Codeforces Round 134 [Rated for Div. 2] | CF1721


    第一次 div2 从 A 冲 到 E 呢!!!

    从来没有靠手速上过分/fad。每次都是靠做难题上分。这次排在 5 题的倒数前 10 名着实有点不甘心呢!!!罚时吃满不用慌!!!不过没事!!!!咱是 OI 赛制,不过记得多写个拍!!

    不过下一次打 CF 都是寒假了吧

    https://codeforces.com/contest/1721

    A

    #include <bits/stdc++.h>
    //#define int long long
    #define pb push_back
    using namespace std;
    char s[6];
    int ct[100];
    void solve() {
    	memset(ct,0,sizeof(ct));
    	cin>>s[1]>>s[2]>>s[3]>>s[4];
    	for(int i=1;i<=4;i++) {
    		++ct[s[i]-'a'];
    //		if(ct[s[i]-'a']>mx) mx=ct[s[i]-'a'];
    	}
    	int cnt1=0,cnt2=0,cnt3=0,cnt4=0;
    	for(int i=0;i<26;i++) {
    		if(ct[i]==1) ++cnt1;
    		else if(ct[i]==2) ++cnt2;
    		else if(ct[i]==3) ++cnt3;
    		else if(ct[i]==4) ++cnt4;
    	}
    	if(cnt4) {
    		cout<<"0\n"; 
    	} else if(cnt3) {
    		cout<<"1\n";
    	} else if(cnt2) {
    		if(cnt2==2) {
    			cout<<"1\n";
    		} else cout<<"2\n";
    	} else cout<<"3\n";
    }
    
    signed main() {
    	cin.tie(0); ios::sync_with_stdio(false);
    	int T; cin>>T; while(T--) solve();
    	return 0;
    } 
    
    

    B

    #include <bits/stdc++.h>
    //#define int long long
    #define pb push_back
    using namespace std;
    int n,m,x,y,d;
    void solve() {
    	cin>>n>>m>>x>>y>>d;
    	int res=n-1+m-1;
    	if(x-d>1&&y+d<m) {
    		cout<<res<<'\n';
    		return ;
    	} 
    	if(x+d<n&&y-d>1) {
    		cout<<res<<'\n'; return ;
    	}
    	cout<<"-1\n";
    }
    
    signed main() {
    	cin.tie(0); ios::sync_with_stdio(false);
    	int T; cin>>T; while(T--) solve();
    	return 0;
    } 
    
    

    C

    有点难度!赛时先写了 D 再来挑战 C!

    考虑若 \(a_i\) 匹配 \(b_j\),那么只要满足 2 个必要条件就能充分了。

    1. \(a_i\le b_j\)

    2. \(a_i,b_j\) 去掉,序列 \(a\),序列 \(b\),对于每个 \(a\) 都能选到 \(b\)。用形式化表达一下,显然 \(a_i\) 选之前 \(a_j,j\in[i+1,n]\) 都得先选好,记 \(a_i\) 能匹配序列 \(b\)\({pp_i}\) 个数,显然要满足 \(n-i+1\le pp_i\)。然后显然我们要维护这个式子,记 \(v_i=pp_i-(n-i+1)\),显然若合法就是 \(\min v_i \ge 0\)。考虑去掉 \(a_i\),那么就是 \(\forall j\in [1,i),v_j+1\),即前面的竞争对手少了一个。去掉 \(b_j\) 同理。

    然后我们会发现我们的式子仅跟原先 \(v_i=0\) 的有关,因为至多 \(-1\) 嘛。考虑大于等于 \(i\) 的已经加 \(1\) 了,显然没啥事,于是扫描线+ multiset 维护下第二个东西就好了。

    #include <bits/stdc++.h>
    //#define int long long
    #define pb push_back
    using namespace std;
    const int N=(int)(2e5+5);
    int n,a[N],b[N],ans[N],v[N],pp[N];
    //
    //bool check(int x,int y) {
    //	for(int i=1;i<x;i++) v[i]++;
    //	for(int i=1;i<=n;i++) {
    //		if(pp[i]<=y) --v[i];
    //	}
    //	// v[i]=0 pp[i]<=y i>x
    ////	int mi=0x3f3f3f3f;
    //	bool fl=1;
    //	for(int i=1;i<=n;i++) {
    //		if(i!=x&&v[i]<0) fl=0;
    //	}
    //	for(int i=1;i<x;i++) --v[i];
    //	for(int i=1;i<=n;i++) if(pp[i]<=y) ++v[i];
    //	return fl;
    //}
    multiset<int>s;
    bool check(int x,int y) {
    	if(s.empty()) return 1;
    	auto qwq=s.upper_bound(y);
    	if(qwq==s.end()) return 0;
    //	cout<<x<<" "<<y<<" "<<*qwq<<'\n';
    	if(qwq==s.begin()) return 1;
    //	if()
    	return 0;
    }
    
    void solve() {
    	cin>>n; s.clear();
    	for(int i=0;i<=n+1;i++) ans[i]=a[i]=b[i]=0;
    	for(int i=1;i<=n;i++) cin>>a[i];
    	for(int i=1;i<=n;i++) cin>>b[i];
    	for(int i=1;i<=n;i++) {
    		pp[i]=lower_bound(b+1,b+1+n,a[i])-b;
    		v[i]=(n-pp[i]+1)-(n-i+1);
    //		cout<<v[i]<<" "<<pp[i]<<'\n';
    	}
    //	cout<<check(1,1)<<'\n';
    	for(int i=n;i>=1;i--) {
    		int l=pp[i],r=n,res=0;
    		while(l<=r) {
    			int mid=(l+r)>>1;
    			if(check(i,mid)) r=mid-1,res=mid;
    			else r=mid-1;
    		}
    		ans[i]=b[res]-a[i];
    		if(v[i]==0) {
    			s.insert(pp[i]);
    		}
    	}
    	for(int i=1;i<=n;i++) cout<<ans[i]<<' ';
    	cout<<'\n';
    	s.clear();
    	for(int i=n;i>=1;i--) {	
    		int l=pp[i],r=n,res=0;
    		while(l<=r) {
    			int mid=(l+r)>>1;
    			if(check(i,mid)) l=mid+1,res=mid;
    			else r=mid-1;
    		}
    		ans[i]=b[res]-a[i];
    		if(v[i]==0) {
    			s.insert(pp[i]);
    		}
    	}
    	for(int i=1;i<=n;i++) cout<<ans[i]<<' ';
    	cout<<'\n';
    }
    
    signed main() {
    	cin.tie(0); ios::sync_with_stdio(false);
    	int T; cin>>T; while(T--) solve();
    	return 0;
    } 
    
    

    D

    image

    #include <bits/stdc++.h>
    //#define int long long
    #define pb push_back
    using namespace std;
    const int N=(int)(5e5+5);
    int n,a[N],b[N],ida[N],idb[N],prea[N],preb[N],cnta0[N],cnta1[N],cntb0[N],cntb1[N];
    vector<int>veca[N],vecb[N];
    void solve() {
    	cin>>n;
    	for(int i=1;i<=n;i++) cin>>a[i];
    	for(int i=1;i<=n;i++) cin>>b[i];
    	int tot=1,ans=0;
    	for(int i=1;i<=n;i++) ida[i]=1,idb[i]=1;
    	for(int i=29;i>=0;i--) {
    		bool ok=1;
    		for(int j=1;j<=n;j++) {
    			if((a[j]>>i)&1) {
    				++cnta1[ida[j]];
    			} else ++cnta0[ida[j]];
    			veca[ida[j]].pb(j);
    		}
    		for(int j=1;j<=n;j++) {
    			if((b[j]>>i)&1) ++cntb1[idb[j]];
    			else ++cntb0[idb[j]];
    			vecb[idb[j]].pb(j);
    		}
    		for(int j=1;j<=tot;j++) {
    //			cout<<cnta0[j]<<" "<<cn
    			if(cnta0[j]==cntb1[j]&&cnta1[j]==cntb0[j]){
    			} else ok=0; 
    		}
    		for(int j=1;j<=n;j++) prea[j]=ida[j],preb[j]=idb[j];
    		if(ok) {
    			int pre=tot; ans+=(1<<i);
    			for(int j=1;j<=pre;j++) {
    				++tot; bool fl=0;
    				for(int x:veca[j]) {
    					if((a[x]>>i)&1) fl=1,ida[x]=tot;
    				}
    				for(int x:vecb[j]) {
    					if(!((b[x]>>i)&1)) fl=1,idb[x]=tot;
    				}
    				if(!fl) --tot;
    				else {
    					bool flll=0;
    					for(int x:veca[j]) {
    						if(!((a[x]>>i)&1)) flll=1;
    					}
    					for(int x:vecb[j]) {
    						if((b[x]>>i)&1) flll=1;
    					}
    					if(!flll) {
    						--tot;
    						for(int x:veca[j]) {
    							if((a[x]>>i)&1) ida[x]=j;
    						}
    						for(int x:vecb[j]) {
    							if(!((b[x]>>i)&1)) idb[x]=j;
    						}
    					}
    				}
    			}
    		}
    		for(int j=1;j<=n;j++) {
    			veca[prea[j]].clear(); vecb[preb[j]].clear();
    			cnta1[prea[j]]=cnta0[prea[j]]=0;
    			cntb1[preb[j]]=cntb0[preb[j]]=0;
    		}
    	}
    	cout<<ans<<'\n';
    //	for(int i=1;i<=tot;i++) veca[i].clear
    }
    
    signed main() {
    	cin.tie(0); ios::sync_with_stdio(false);
    	int T; cin>>T; while(T--) solve();
    	return 0;
    } 
    
    

    E

    暴力发现会 T,加速下当前第 \(i\) 然后要匹配 \(c\) 要跳到哪里就好了。

    预处理的复杂度是线性的。

    类失配树?

    #include <bits/stdc++.h>
    //#define int long long
    #define pb push_back
    using namespace std;
    const int N=(int)(1e6+20);
    char s[N],t[20];
    int n,m,q,nex[N],NEX[N][26];
    signed main() {
    	cin.tie(0); ios::sync_with_stdio(false);
    	cin>>s+1; n=strlen(s+1);
    	int kmpj=0;
    	for(int i=2;i<=n;i++) {
    		while(kmpj&&s[kmpj+1]!=s[i]) kmpj=nex[kmpj];
    		if(s[kmpj+1]==s[i]) ++kmpj;
    		nex[i]=kmpj;
    	}
    	for(int i=1;i<=n+10;i++) {
    		for(int j=0;j<26;j++) NEX[i][j]=-1;
    	}
    	for(int i=1;i<n;i++) {
    		for(int j=0;j<26;j++) {
    			int x=i;
    			while(1) {
    				if(s[x+1]==j+'a') {
    					NEX[i][j]=x; break ;
    				}
    				x=nex[x];
    				if(NEX[x][j]!=-1) {
    					NEX[i][j]=NEX[x][j]; break ;
    				}
    			}
    			if(NEX[i][j]==-1) NEX[i][j]=0;
    		}
    	}
    	int qwq=kmpj;
    	cin>>q;
    	while(q--) {
    		cin>>t+1; m=strlen(t+1);
    		int tot=n; kmpj=qwq;
    		for(int i=1;i<=m;i++) {
    			s[++tot]=t[i];
    		}
    		for(int i=n+1;i<=tot;i++) {
    			while(kmpj&&s[kmpj+1]!=s[i]) {
    				if(kmpj<n) {
    					kmpj=NEX[kmpj][s[i]-'a'];
    				} else kmpj=nex[kmpj];
    			}
    			if(s[kmpj+1]==s[i]) ++kmpj;
    			nex[i]=kmpj;
    			cout<<nex[i]<<' ';
    		}
    		cout<<'\n';
    		for(int i=n+1;i<=tot;i++) nex[i]=0,s[i]=0;
    	}
    	return 0;
    } 
    
    

    F

  • 相关阅读:
    自己觉得好的文章(2)
    为什么要用C运行时库的_beginthreadex代替操作系统的CreateThread来创建线程?
    GraphEdit
    吴裕雄天生自然Spring BootSpring Boot与Thymeleaf实现页面信息国际化
    吴裕雄天生自然Spring BootThymeleaf基础语法
    吴裕雄天生自然Spring BootSpring Boot处理JSON数据
    吴裕雄天生自然Spring Boot基于Thymeleaf与BootStrap的Web开发实例
    吴裕雄天生自然Spring Boot基本配置和注解
    吴裕雄天生自然Spring Boot自定义Starters
    吴裕雄天生自然Spring Boot的基本配置
  • 原文地址:https://www.cnblogs.com/xugangfan/p/16633309.html
Copyright © 2020-2023  润新知