zoukankan      html  css  js  c++  java
  • CR668 题解

    比赛入口

    C. Fixed Point Removal

    我们预处理一个数组,\(p_i\) 表示若想要删除 \(i\) 的最晚起点。

    显然若 \(a_i=i\)\(p_i=i\),若 \(a_i<i\)\(p_i\) 为前面的第 \(i-a_i\) 大,这可以树状数组上二分做。

    离线询问,每个询问即区间 \([l,r]\) 之间 \(p_i>=l\) 的个数,树状数组可做。

    代码懒得写了,蒯了 \(verdandi\) 的用着:

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=3e5+10;
    inline int read(){
    	int x=0,f=1;char c=getchar();
    	while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    	while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+c-'0';c=getchar();}
    	return x*f;
    }
    int n,m;
    int a[maxn],ans[maxn],tr[maxn];
    #define pii pair<int,int>
    #define fi first
    #define se second
    #define mkp make_pair
    #define pb push_back
    vector<pii>v[maxn];
    void update(int x,int v){
    	for(int i=x;i<=n;i+=i&(-i))tr[i]+=v;
    }
    int query(int x){
    	int res=0;
    	for(int i=x;i;i-=i&(-i))res+=tr[i];
    	return res;
    }
    int getkth(int k){
    	int res=0;
    	for(int i=18;i>=0;i--)
    		if(res+(1<<i)<=n&&k>tr[res+(1<<i)])
    			k-=tr[res+(1<<i)],res+=(1<<i);
    	return res+1;
    }
    int main(){
    	n=read(),m=read();
    	for(int i=1;i<=n;i++)
    		a[i]=read();
    	for(int i=1,x,y;i<=m;i++){
    		x=read()+1,y=n-read();
    		if(x<=y)v[y].pb(mkp(x,i));
    	}
    	for(int i=1;i<=n;i++){
    		if(i-a[i]>=0){
    			int pos=getkth(a[i]);
    			update(min(i+1,pos),1);
    		}else update(1,1);
    		for(int j=0;j<v[i].size();j++)
    			ans[v[i][j].se]=i-query(v[i][j].fi);
    	}
    	for(int i=1;i<=m;i++)
    		printf("%d\n",ans[i]);
    	return 0;
    }
    

    D. Game of Pairs

    题意:交互,给定 \(n\) ,选择先后手,先手需要构造将 \(1\)\(2n\) 分为 \(n\) 对,使得不存在一种方案从每对中选一个和为 \(2n\) 的倍数;后手需要在交互库给定的 \(n\) 对中每对选出一个数使得和为 \(2n\) 的倍数。

    考虑何时先手必胜。若 \(n=1\) 时显然先手负,\(n=2\) 时先手胜,不妨猜测 \(n\) 为偶数时先手必胜。事实的确如此,我们把 \(i\)\(i+n\) 放在一对,那么选出来的数必定是 \(\frac 12 n(n+1)+kn\) 不是 \(2n\) 的倍数。再考虑为什么 \(n\) 为奇数时必负。我们还是希望取出来的数能够是模 \(n\) 意义下的完全剩余系,这样如果我们取出的方案不行,则留下的一定行。考虑每对间连边,\(i\)\(i+n\) 之间连边,每个点的度数均为 \(2\) ,故会形成若干简单偶环,此时将图二分图染色,不难发现 \(i\)\(i+n\) 总不同色,故方案合法。

    #include<bits/stdc++.h>
    using namespace std;
    #define inf 1e9
    const int maxn=1e6+10;
    const int mod=1e9+7;
    inline int read(){
    	int x=0,f=1;char c=getchar();
    	while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    	while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+c-'0';c=getchar();}
    	return x*f;
    }
    int n,m,p[maxn],G[maxn],las[maxn],col[maxn],t[maxn],S;
    inline void dfs(int x,int cur){
    	if(col[x])return;col[x]=cur;
    	dfs(G[x],3-cur);dfs((x+n-1)%(n+n)+1,3-cur);
    }
    int main(){
    	n=read();
    	if(n%2==0){
    		cout<<"First"<<endl;
    		for(int i=1;i<=n;i++)cout<<i<<" ";
    		for(int i=1;i<=n;i++)cout<<i<<" ";
    		cout<<endl;
    	}else{
    		cout<<"Second"<<endl;
    		for(int i=1;i<=n+n;i++){
    			p[i]=read();
    			if(las[p[i]])
    				G[las[p[i]]]=i,G[i]=las[p[i]];
    			else las[p[i]]=i;
    		}
    		for(int i=1;i<=n+n;i++)
    			if(!col[i])dfs(i,1);
    		for(int i=1;i<=n+n;i++)
    			if(col[i]==1)S=(S+i)%(n+n);
    		int flg=(S?2:1);
    		for(int i=1;i<=n+n;i++)
    			if(col[i]==flg)printf("%d ",i);
    		cout<<endl;
    	}
        return 0;
    }//
    
  • 相关阅读:
    洛谷 P1508 Likecloud-吃、吃、吃
    Codevs 1158 尼克的任务
    2017.10.6 国庆清北 D6T2 同余方程组
    2017.10.6 国庆清北 D6T1 排序
    2017.10.3 国庆清北 D3T3 解迷游戏
    2017.10.3 国庆清北 D3T2 公交车
    2017.10.3 国庆清北 D3T1 括号序列
    2017.10.4 国庆清北 D4T1 财富
    2017.10.7 国庆清北 D7T2 第k大区间
    2017.10.7 国庆清北 D7T1 计数
  • 原文地址:https://www.cnblogs.com/syzf2222/p/15765954.html
Copyright © 2011-2022 走看看