zoukankan      html  css  js  c++  java
  • Codeforces Global Round 3

    Codeforces Global Round 3

    B - Born This Way

    首先二分从B到C坐的是哪个航班,然后枚举从A到B坐的是哪个航班即可。

    #include<bits/stdc++.h>
    #define qmin(x,y) (x=min(x,y))
    #define qmax(x,y) (x=max(x,y))
    #define pir pair<int,int>
    #define mp(x,y) make_pair(x,y)
    #define fr first
    #define sc second
    #define rsort(x,y) sort(x,y),reverse(x,y)
    #define vic vector<int>
    #define vit vic::iterator
    using namespace std;
    
    char gc() {
    //	static char buf[100000],*p1,*p2;
    //	return (p1==p2)&&(p2=(p1=buf)+fread(buf,1,100000,stdin))?EOF:*p1++;
    	return getchar();
    }
    
    template<class T>
    int read(T &ans) {
    	T f=1;ans=0;
    	char ch=gc();
    	while(!isdigit(ch)) {
    		if(ch==EOF) return EOF;
    		if(ch=='-') f=-1;
    		ch=gc();
    	}
    	while(isdigit(ch))
    		ans=ans*10+ch-'0',ch=gc();
    	ans*=f;return 1;
    }
    
    template<class T1,class T2>
    int read(T1 &a,T2 &b) {
    	return read(a)==EOF?EOF:read(b);
    }
    
    template<class T1,class T2,class T3>
    int read(T1 &a,T2 &b,T3 &c) {
    	return read(a,b)==EOF?EOF:read(c);
    }
    
    typedef long long ll;
    const int Maxn=1100000;
    const int inf=0x3f3f3f3f;
    const ll mod=998244353;
    
    int n,m,k;
    ll a[Maxn],b[Maxn],ta,tb;
    
    bool check(int x) {
    	int temp=1;
    	if(n<=k||m<=k) return true;
    	for(int i=1;i<=n;i++) {
    		while(b[temp]<a[i]+ta&&temp<x) temp++;
    		if(i-1+x-temp<=k) return true;
    	}
    	return false;
    }
    
    int main() {
    //	freopen("test.in","r",stdin);
    	read(n,m);
    	read(ta,tb,k);
    	for(int i=1;i<=n;i++) read(a[i]);
    	for(int i=1;i<=m;i++) read(b[i]);
    	b[m+1]=(ll)inf<<2ll;
    	if(check(m+1)) {
    		puts("-1");
    	}
    	else {
    		int l=1,r=m,mid=l+r>>1,ans;
    		while(l<=r) {
    			if(check(mid)) {
    				ans=mid;
    				l=mid+1;
    			}
    			else r=mid-1;
    			mid=l+r>>1;
    		}
    		printf("%I64d
    ",b[ans]+tb);
    	}
    	return 0;
    }
    

    C - Crazy Diamond

    首先考虑2到n-1中的每一个数,如果这个数应该放在左半边,那么可以考虑把这个数从当前位置移动到n,然后移动到应该放的位置。而移动到n的时候如果这个数是在左半边,就直接移动,否则先移动到1再移动到n。右半边同理。最后特判一下1和n即可。移动的次数为3n。

    #include<bits/stdc++.h>
    #define qmin(x,y) (x=min(x,y))
    #define qmax(x,y) (x=max(x,y))
    #define pir pair<int,int>
    #define mp(x,y) make_pair(x,y)
    #define fr first
    #define sc second
    #define rsort(x,y) sort(x,y),reverse(x,y)
    #define vic vector<int>
    #define vit vic::iterator
    using namespace std;
    
    char gc() {
    //	static char buf[100000],*p1,*p2;
    //	return (p1==p2)&&(p2=(p1=buf)+fread(buf,1,100000,stdin))?EOF:*p1++;
    	return getchar();
    }
    
    template<class T>
    int read(T &ans) {
    	T f=1;ans=0;
    	char ch=gc();
    	while(!isdigit(ch)) {
    		if(ch==EOF) return EOF;
    		if(ch=='-') f=-1;
    		ch=gc();
    	}
    	while(isdigit(ch))
    		ans=ans*10+ch-'0',ch=gc();
    	ans*=f;return 1;
    }
    
    template<class T1,class T2>
    int read(T1 &a,T2 &b) {
    	return read(a)==EOF?EOF:read(b);
    }
    
    template<class T1,class T2,class T3>
    int read(T1 &a,T2 &b,T3 &c) {
    	return read(a,b)==EOF?EOF:read(c);
    }
    
    typedef long long ll;
    const int Maxn=1100000;
    const int inf=0x3f3f3f3f;
    const ll mod=998244353;
    
    int n,p[Maxn],b[Maxn],tot;
    pir ans[Maxn];
    
    void work(int x,int y) {
    	ans[++tot]=mp(x,y);
    	b[p[x]]=y;
    	b[p[y]]=x;
    	swap(p[x],p[y]);
    }
    
    int main() {
    //	freopen("test.in","r",stdin);
    	read(n);
    	for(int i=1;i<=n;i++) read(p[i]),b[p[i]]=i;
    	for(int i=2;i<=n/2;i++) {
    		if(p[i]==i) continue;
    		if(b[i]<=n/2) {
    			work(b[i],n);
    			work(n,i);
    		}
    		else {
    			work(b[i],1);
    			work(1,n);
    			work(n,i);
    		}
    	}
    	for(int i=n/2+1;i<n;i++) {
    		if(p[i]==i) continue;
    		if(b[i]>n/2) {
    			work(b[i],1);
    			work(1,i);
    		}
    		else {
    			work(b[i],n);
    			work(1,n);
    			work(1,i);
    		}
    	}
    	if(p[1]!=1) work(1,n);
    	printf("%d
    ",tot);
    	for(int i=1;i<=tot;i++)
    		printf("%d %d
    ",ans[i].fr,ans[i].sc);
    	return 0;
    }
    

    D - Dirty Deeds Done Dirt Cheap

    有两种类型的数列,第一种是第一个数比第二个数大,而第二种是第一个数比第二个数小。

    那么如果(a_i<b_i),这对数一定要放在第二种,否则放在第一种。

    考虑第一种数列,要让数列形成波浪形,就要满足(b_{i-1}<a_i),又因为(b_{i-1}<a_{i-1}),所以只要按照a从小到大排序即可。对于第二种数列同理。

    #include<bits/stdc++.h>
    #define qmin(x,y) (x=min(x,y))
    #define qmax(x,y) (x=max(x,y))
    #define pir pair<int,int>
    #define mp(x,y) make_pair(x,y)
    #define fr first
    #define sc second
    #define rsort(x,y) sort(x,y),reverse(x,y)
    #define vic vector<int>
    #define vit vic::iterator
    using namespace std;
    
    char gc() {
    //	static char buf[100000],*p1,*p2;
    //	return (p1==p2)&&(p2=(p1=buf)+fread(buf,1,100000,stdin))?EOF:*p1++;
    	return getchar();
    }
    
    template<class T>
    int read(T &ans) {
    	T f=1;ans=0;
    	char ch=gc();
    	while(!isdigit(ch)) {
    		if(ch==EOF) return EOF;
    		if(ch=='-') f=-1;
    		ch=gc();
    	}
    	while(isdigit(ch))
    		ans=ans*10+ch-'0',ch=gc();
    	ans*=f;return 1;
    }
    
    template<class T1,class T2>
    int read(T1 &a,T2 &b) {
    	return read(a)==EOF?EOF:read(b);
    }
    
    template<class T1,class T2,class T3>
    int read(T1 &a,T2 &b,T3 &c) {
    	return read(a,b)==EOF?EOF:read(c);
    }
    
    typedef long long ll;
    const int Maxn=1100000;
    const int inf=0x3f3f3f3f;
    const ll mod=998244353;
    
    int n,a[Maxn],b[Maxn],tot,cnt;
    pir c[Maxn],d[Maxn];
    
    int main() {
    //	freopen("test.in","r",stdin);
    	read(n);
    	for(int i=1;i<=n;i++) {
    		read(a[i],b[i]);
    		if(a[i]<=b[i]) c[++tot]=mp(a[i],i);
    		else d[++cnt]=mp(a[i],i);
    	}
    	if(tot>cnt) {
    		printf("%d
    ",tot);
    		rsort(c+1,c+tot+1);
    		for(int i=1;i<=tot;i++) printf("%d ",c[i].sc);
    	}
    	else {
    		printf("%d
    ",cnt);
    		sort(d+1,d+cnt+1);
    		for(int i=1;i<=cnt;i++) printf("%d ",d[i].sc);
    	}
    	return 0;
    }
    

    E - Earth Wind and Fire

    首先石子的相对顺序是不会改变的,因为如果一个石子在移动的过程中跨过了另一个石子,那么只需要把这个石子移动到那个石子上,然后移动那个石子即可。

    这样,对于每一个石子,就确定下来最终要移动到哪个位置,记向右走为正,向左走为负,对偏移量做一个类似括号序列的东西即可。

    #include<bits/stdc++.h>
    #define qmin(x,y) (x=min(x,y))
    #define qmax(x,y) (x=max(x,y))
    #define pir pair<int,int>
    #define mp(x,y) make_pair(x,y)
    #define fr first
    #define sc second
    #define rsort(x,y) sort(x,y),reverse(x,y)
    #define vic vector<int>
    #define vit vic::iterator
    using namespace std;
    
    char gc() {
    //	static char buf[100000],*p1,*p2;
    //	return (p1==p2)&&(p2=(p1=buf)+fread(buf,1,100000,stdin))?EOF:*p1++;
    	return getchar();
    }
    
    template<class T>
    int read(T &ans) {
    	T f=1;ans=0;
    	char ch=gc();
    	while(!isdigit(ch)) {
    		if(ch==EOF) return EOF;
    		if(ch=='-') f=-1;
    		ch=gc();
    	}
    	while(isdigit(ch))
    		ans=ans*10+ch-'0',ch=gc();
    	ans*=f;return 1;
    }
    
    template<class T1,class T2>
    int read(T1 &a,T2 &b) {
    	return read(a)==EOF?EOF:read(b);
    }
    
    template<class T1,class T2,class T3>
    int read(T1 &a,T2 &b,T3 &c) {
    	return read(a,b)==EOF?EOF:read(c);
    }
    
    typedef long long ll;
    const int Maxn=1100000;
    const int inf=0x3f3f3f3f;
    const ll mod=998244353;
    
    int n,top,s[Maxn],tot;
    ll a[Maxn],b[Maxn];
    pair<ll,int> p[Maxn];
    pair<pir,ll> ans[Maxn];
    
    void add(int x,int y,int z) {
    	ans[++tot]=mp(mp(x,y),z);
    }
    
    int main() {
    //	freopen("test.in","r",stdin);
    	read(n);
    	for(int i=1;i<=n;i++) read(a[i]),p[i]=mp(a[i],i);
    	for(int i=1;i<=n;i++) read(b[i]);
    	sort(p+1,p+n+1);
    	sort(b+1,b+n+1);
    	for(int i=1;i<=n;i++) a[i]=b[i]-p[i].fr;
    	ll temp=0;
    	for(int i=1;i<=n;i++) temp+=a[i];
    	if(temp) return 0*puts("NO");
    	for(int i=1;i<=n;i++) {
    		if(a[i]<0) {
    			while(top) {
    				int temp=min(-a[i],a[s[top]]);
    				if(!temp) {
    					top--;
    					continue;
    				}
    				add(p[s[top]].sc,p[i].sc,min(-a[i],a[s[top]]));
    				a[i]+=temp;
    				a[s[top]]-=temp;
    				if(a[i]==0) break;
    			}
    			if(a[i]<0) return 0*puts("NO");
    		}
    		else s[++top]=i;
    	}
    	puts("YES");
    	printf("%d
    ",tot);
    	for(int i=1;i<=tot;i++) {
    		printf("%d %d %I64d
    ",ans[i].fr.fr,ans[i].fr.sc,ans[i].sc);
    	}
    	return 0;
    }
    

    F - Foo Fighters

    从低位到高位考虑,枚举每个最高位等于这个位的数,计算出其当前的实际价值,然后求和,如果和的符号和整体的和的符号相同,那么就将这一位变号。每一个数只会被访问到一次,时间复杂度为(O(n2^n))

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #include<cctype>
    #define qmin(x,y) (x=min(x,y))
    #define qmax(x,y) (x=max(x,y))
    #define vic vector<int>
    #define vit vic::iterator
    #define pir pair<int,int>
    #define fr first
    #define sc second
    #define mp(x,y) make_pair(x,y)
    #define rsort(x,y) sort(x,y),reverse(x,y)
    using namespace std;
    
    inline char gc() {
    //	static char buf[100000],*p1,*p2;
    //	return (p1==p2)&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
    	return getchar();
    }
    
    template<class T>
    int read(T &ans) {
    	ans=0;char ch=gc();T f=1;
    	while(!isdigit(ch)) {
    		if(ch==EOF) return -1;
    		if(ch=='-') f=-1;
    		ch=gc();
    	}
    	while(isdigit(ch))
    		ans=ans*10+ch-'0',ch=gc();
    	ans*=f;return 1;
    }
    
    template<class T1,class T2>
    int read(T1 &a,T2 &b) {
    	return read(a)!=EOF&&read(b)!=EOF?2:EOF;
    }
    
    template<class T1,class T2,class T3>
    int read(T1 &a,T2 &b,T3 &c) {
    	return read(a,b)!=EOF&&read(c)!=EOF?3:EOF;
    }
    
    typedef long long ll;
    const int Maxn=1100000;
    const int inf=0x3f3f3f3f;
    
    int n;
    ll s,ans;
    pair<ll,ll> a[Maxn];
    
    ll work(ll x) {
    	ll f=1;
    	while(x) {
    		if(x&1) f*=-1;
    		x>>=1;
    	}
    	return f;
    }
    
    signed main() {
    //	freopen("test.in","r",stdin);
    	read(n);
    	for(int i=1;i<=n;i++) read(a[i].fr,a[i].sc);
    	for(int i=1;i<=n;i++) s+=a[i].fr;
    	sort(a+1,a+n+1,[&](pair<ll,ll> a,pair<ll,ll> b) {
    		return a.sc<b.sc;
    	});
    	a[n+1].sc=0x7fffffffffffffff;
    	int temp=1;
    	for(ll i=2;temp<=n;i<<=1) {
    		int x=temp;
    		while(a[x].sc<i) x++;
    		ll sum=0;
    		for(int j=temp;j<x;j++) sum+=work(a[j].sc&ans)*a[j].fr;
    		if((sum<0)==(s<0)&&(sum>0)==(s>0)) ans|=(i>>1);
    		temp=x;
    	}
    	printf("%lld
    ",ans);
    	return 0;
    }
    

    G - Gold Experience

    首先贪心地求出来补图中的一个独立集,这个独立集中每对数其最大公约数大于一,这个可以用莫比乌斯函数在(2^8)的时间内求出。

    如果独立集大小大于等于(k),那么就得到了答案,否则的话补图中的联通块数一定小于(k),因为(k<2n)那么点数不为1的联通块中的总点数也一定大于(k)。那么就把这些点找出来即可,可以用整体二分。

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #include<cctype>
    #define qmin(x,y) (x=min(x,y))
    #define qmax(x,y) (x=max(x,y))
    #define vic vector<int>
    #define vit vic::iterator
    #define pir pair<int,int>
    #define fr first
    #define sc second
    #define mp(x,y) make_pair(x,y)
    #define rsort(x,y) sort(x,y),reverse(x,y)
    using namespace std;
    
    inline char gc() {
    //	static char buf[100000],*p1,*p2;
    //	return (p1==p2)&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
    	return getchar();
    }
    
    template<class T>
    int read(T &ans) {
    	ans=0;char ch=gc();T f=1;
    	while(!isdigit(ch)) {
    		if(ch==EOF) return -1;
    		if(ch=='-') f=-1;
    		ch=gc();
    	}
    	while(isdigit(ch))
    		ans=ans*10+ch-'0',ch=gc();
    	ans*=f;return 1;
    }
    
    template<class T1,class T2>
    int read(T1 &a,T2 &b) {
    	return read(a)!=EOF&&read(b)!=EOF?2:EOF;
    }
    
    template<class T1,class T2,class T3>
    int read(T1 &a,T2 &b,T3 &c) {
    	return read(a,b)!=EOF&&read(c)!=EOF?3:EOF;
    }
    
    typedef long long ll;
    const int Maxn=110000;
    const int Maxm=11000000;
    const int inf=0x3f3f3f3f;
    
    int bj[Maxm],pi[Maxm],tot,f[Maxm],mu[Maxm];
    int n,a[Maxn],k;
    vic A,B,C[Maxn],d[Maxn];
    pir p[Maxn];
    
    void pre(int x) {
    	mu[1]=1;
    	for(int i=2;i<=x;i++) {
    		if(!bj[i]) {
    			pi[++tot]=i;
    			f[i]=tot;
    			mu[i]=-1;
    		}
    		int j=0,temp;
    		while((temp=i*pi[++j])<=x) {
    			bj[temp]=1;
    			f[temp]=j;
    			if(i%pi[j]==0) {
    				mu[temp]=mu[i]*pi[j];
    				break;
    			}
    			mu[temp]=mu[i]*mu[pi[j]];
    		}
    	}
    }
    
    int query(int x,int cnt,int y) {
    	if(cnt==d[x].size()) return bj[y];
    	return query(x,cnt+1,y)+query(x,cnt+1,y*d[x][cnt]);
    }
    
    void add(int x,int cnt,int y) {
    	if(cnt==d[x].size()) {
    		bj[y]+=mu[y];
    		return ;
    	}
    	add(x,cnt+1,y),add(x,cnt+1,y*d[x][cnt]);
    }
    
    void del(int x,int cnt,int y) {
    	if(cnt==d[x].size()) {
    		bj[y]=0;
    		return ;
    	}
    	del(x,cnt+1,y),del(x,cnt+1,y*d[x][cnt]);
    }
    
    void solve(int l,int r,vic v) {
    	if(v.empty()) return ;
    	if(l==r) {
    		C[l]=v;
    		return ;
    	}
    	vic ls,rs;
    	int mid=l+r>>1;
    	for(int i=l;i<=mid;i++) add(A[i],0,1);
    	for(auto i:v)
    		if(query(i,0,1)) ls.push_back(i);
    		else rs.push_back(i);
    	for(int i=l;i<=mid;i++) del(A[i],0,1);
    	solve(l,mid,ls),solve(mid+1,r,rs);
    }
    
    signed main() {
    //	freopen("test.in","r",stdin);
    	read(n,k);
    	for(int i=1;i<=n;i++) read(a[i]);
    	pre(10000000); memset(bj,0,sizeof(bj));
    	for(int i=1;i<=n;i++) {
    		int x=a[i];
    		while(x!=1) {
    			int y=pi[f[x]];
    			d[i].push_back(y);
    			while(x%y==0) x/=y;
    		}
    		if(!query(i,0,1)) A.push_back(i),add(i,0,1);
    		else B.push_back(i);
    	}
    	if(A.size()>=k) {
    		for(int i=0;i<k;i++) printf("%d ",A[i]);
    		return 0;
    	}
    	for(auto i:A) del(i,0,1);
    	solve(0,A.size()-1,B);
    	int sum=0;
    	for(int i=0;i<A.size();i++) p[i]=mp(C[i].size(),i);
    	rsort(p,p+A.size());
    	for(int i=0;i<A.size();i++) {
    		sum+=p[i].fr+1;
    		if(sum>=k) {
    			int ned=k-(i+1)*2;
    			vic ans;
    			for(int j=0;j<=i;j++) {
    				int x=min(p[j].fr-1,ned);
    				ned-=x;
    				x++; ans.push_back(A[p[j].sc]);
    				for(int k=0;k<x;k++) ans.push_back(C[p[j].sc][k]);
    			}
    			for(auto i:ans) printf("%d ",i);
    			return 0;
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    Oracle 11g SQL Fundamentals Training Introduction02
    Chapter 05Reporting Aggregated data Using the Group Functions 01
    Chapter 01Restriicting Data Using The SQL SELECT Statemnt01
    Oracle 11g SQL Fundamentals Training Introduction01
    Chapter 04Using Conversion Functions and Conditional ExpressionsConditional Expressions
    Unix时代的开创者Ken Thompson (zz.is2120.bg57iv3)
    我心目中计算机软件科学最小必读书目 (zz.is2120)
    北京将评估分时分区单双号限行 推进错时上下班 (zz)
    佳能G系列领军相机G1X
    选购单反相机的新建议——心民谈宾得K5(转)
  • 原文地址:https://www.cnblogs.com/shanxieng/p/11084758.html
Copyright © 2011-2022 走看看