zoukankan      html  css  js  c++  java
  • Lg 8月赛(构造+交互)

    Div2

    得分 (270pts' = 100 + 100 + 0 +70)

    T1「PMOI-4」人赢

    打表找规律,大概是每 6 个一个周期。

    正经做法是用矩阵加速维护指数,同时用扩展欧拉定理处理模数

    #include<bits/stdc++.h>
    
    using namespace std;
    
    #define int long long
    
    template<typename _T>
    inline void read(_T &x)
    {
    	x=0;char s=getchar();int f=1;
    	while(s<'0'||s>'9') {f=1;if(s=='-')f=-1;s=getchar();}
    	while('0'<=s&&s<='9'){x=(x<<3)+(x<<1)+s-'0';s=getchar();}
    	x*=f;
    }
    
    int a[2333333];
    //int a1[23333],a2[23333];
    int n,m,k;
    
    signed  main()
    {
    	read(n);
    	read(m);
    	read(k);
    	a[1]= n;
    	a[2] = m;
    	for(int i=3;i<=100;i++) a[i] = a[i-1] * a[i-2] % 10;//,cout<<a[i]<<" ";
    	
    	int op = k;
    	k-= 2;
    	if(k <= 6) printf("%lld
    ",a[2 + k]);
    	else
    	{
    		k = k % 6;
    		if(!k) k = 6;
    		printf("%lld
    ",a[2 + k]);		
    	}
    //	printf("%lld",a[op]);
    
     }
    

    T2「PMOI-4」可怜的团主

    贪心就行,用 deque 来维护。(还重构了一次

    #include<bits/stdc++.h>
    
    using namespace std;
    
    #define int long long
    #define pb push_back
    
    template<typename _T>
    inline void read(_T &x)
    {
    	x=0;char s=getchar();int f=1;
    	while(s<'0'||s>'9') {f=1;if(s=='-')f=-1;s=getchar();}
    	while('0'<=s&&s<='9'){x=(x<<3)+(x<<1)+s-'0';s=getchar();}
    	x*=f;
    }
    
    const int INF = 1e18;
    const int np = 1e5 + 5;
    int a[np];
    int b1[np],b2[np],b3[np],b4[np];
    int t1,t2,t3,t4;
    deque<int> fu[2],zh[2];
    
    inline int Abs(int x){return x < 0?-x:x;}
    
    inline bool cmp(int a,int b)
    {
    	return Abs(a) > Abs(b);
    }
    signed  main()
    {
    	int n;
    	read(n);
    	for(int i=1;i<=n;i++) read(a[i]);
    	sort(a + 1,a + 1 + n);
    	for(int i=1;i<=n;i++)
    	{
    		if(a[i] < 0)
    		{
    			int op = Abs(a[i]);
    			if(op & 1) b1[++t1] = a[i];//fu[1].pb(a[i]);
    			else b2[++t2] = a[i];//fu[0].pb(a[i]);
    		}
    		else
    		{
    			int op = Abs(a[i]);
    			if(op & 1) b3[++t3] = a[i];//zh[1].pb(a[i]);
    			else b4[++t4] = a[i];//zh[0].pb(a[i]);
    		}
    	}
    	
    	sort(b1 + 1,b1 + 1 + t1,cmp);//1
    	for(int i=1;i<=t1;i++) fu[1].pb(b1[i]);
    	sort(b2 + 1,b2 + 1 + t2,cmp);//2
    	for(int i=1;i<=t2;i++) fu[0].pb(b2[i]);
    	sort(b3 + 1,b3 + 1 + t3,cmp);//3
    	for(int i=1;i<=t3;i++) zh[1].pb(b3[i]);
    	sort(b4 + 1,b4 + 1 + t4,cmp);//4
    	for(int i=1;i<=t4;i++) zh[0].pb(b4[i]);
    	
    	int Ans = 0;
    	
    	for(int i=1;i<=n;i++)
    	{
    		if(i & 1)
    		{
    			int op1 = zh[0].size() ? zh[0].front():-INF;
    			int op2 = fu[1].size() ? fu[1].front():-INF;
    			if(op1 == -INF && op2 == -INF)
    			{
    				op1 = zh[1].size() ? zh[1].back():-INF;
    				op2 = fu[0].size() ? fu[0].back():-INF;				
    				if((op1 != -INF && op2 != -INF && op1 < Abs(op2)) ||(op1!=-INF && op2 == -INF))
    				{
    					Ans += op1;
    					Ans -= (n-i) * op1;
    					zh[1].pop_back();
    				}
    				if((op1!=-INF&&op2!=-INF&&op1 > Abs(op2))||(op1==-INF && op2!=-INF))
    				{
    					Ans += op2;
    					Ans += (n-i) * op2;
    					fu[0].pop_back();
    				}
    				continue;
    			}
    			if((op1 != -INF && op2 != -INF && op1 > Abs(op2)) ||(op1!=-INF && op2 == -INF))
    			{
    				Ans += op1;
    				Ans += (n-i) * op1;
    				zh[0].pop_front();
    			}
    			if((op1!=-INF&&op2!=-INF&&op1 < Abs(op2))||(op1==-INF && op2!=-INF))
    			{
    				Ans += op2;
    				Ans += (n-i) * Abs(op2);
    				fu[1].pop_front();
    			}
    		}
    		else
    		{
    			int op1 = zh[1].size() ? zh[1].front():-INF;
    			int op2 = fu[0].size() ? fu[0].front():-INF;
    			if(op1 == -INF && op2 == -INF)
    			{
    				op1 = zh[0].size() ? zh[0].back():-INF;
    				op2 = fu[1].size() ? fu[1].back():-INF;				
    				if((op1 != -INF && op2 != -INF && op1 < Abs(op2)) ||(op1!=-INF && op2 == -INF))
    				{
    					Ans += op1;
    					Ans -= (n-i) * op1;
    					zh[0].pop_back();
    				}
    				if((op1!=-INF&&op2!=-INF&&op1 > Abs(op2))||(op1==-INF && op2!=-INF))
    				{
    					Ans += op2;
    					Ans += (n-i) * op2;
    					fu[1].pop_back();
    				}
    				continue;				
    			}
    			if((op1 != -INF && op2 != -INF && op1 > Abs(op2)) ||(op1!=-INF && op2 == -INF))
    			{
    				Ans += op1;
    				Ans += (n-i) * op1;
    				zh[1].pop_front();
    			}
    			if((op1!=-INF&&op2!=-INF&&op1 < Abs(op2))||(op1==-INF && op2!=-INF))
    			{
    				Ans += op2;
    				Ans += (n-i) * Abs(op2);
    				fu[0].pop_front();
    			}			
    		}
    	}
    
    	printf("%lld",Ans);
     }
    
    

    T3「PMOI-4」可怜的团主
    太菜了,图上二选一都没做过。

    这里给出做法:

    首先对原图建出 DFS 树,然后将叶子结点取出。记叶子结点个数为 (L),如果 (L geq lfloorfrac{n}{3} floor),直接取出叶子作为独立集。

    若小于,则先在叶子集合中加入根节点,若(L+1 mod 2=1),则再加入一次根节点。

    然后按 (dfn) 序排序,将 (i)(mid + i) 进行配对,形成不超过 (lceilfrac{n}{6} ceil) 条路径

    证明正确性:

    考虑一个点,若叶子全在它的子树内,那么总会有某个点和根配对,从而导致这个点被覆盖。

    若只有一部分叶子在它的子树内,那么一定存在一些叶子和子树外面的叶子匹配,从而导致这个点被覆盖。

    综上所述,所有的点都会被覆盖。

    #include<bits/stdc++.h>
    
    using namespace std;
    template<typename _T>
    inline void read(_T &x)
    {
    	x=0;char s=getchar();int f=1;
    	while(s<'0'||s>'9') {f=1;if(s=='-')f=-1;s=getchar();}
    	while('0'<=s&&s<='9'){x=(x<<3)+(x<<1)+s-'0';s=getchar();}
    	x*=f;
    }
    const int np = 1e3 + 5;
    const int mp = 1e6 + 5;
    int n,m;
    int head[np],ver[mp * 2],nxt[mp * 2],tit;
    int vis[np],dfn[np],leaf[np],lim,top;
    int qaq[np],dep[np],f[20][np],lg[np],sta[np],arc[np];
    inline void add(int x,int y)
    {
    	ver[++tit] = y;
    	nxt[tit] = head[x];
    	head[x] = tit;
    }
    
    inline void dfs(int x,int ff)
    {
    	vis[x] = 1,dfn[x] = ++ lim;
    	dep[x] = dep[ff] + 1;
    	f[0][x] = ff;
    	int son(0);
    	for(int i=head[x],v;i;i=nxt[i])
    	{
    		v = ver[i];
    		if(vis[v]) continue;
    		son++;
    		dfs(v,x);
    	}
    	if(!son) leaf[++top]=x;
    }
    
    inline int lca_(int u,int v)
    {
    	if(dep[u] < dep[v]) swap(u,v);
    	int delta = dep[u] - dep[v];
    	for(int i=lg[delta];i>=0;i--)
    	if(dep[f[i][u]] >= dep[v]) u = f[i][u];
    	if(u == v) return u;
    	delta = dep[v];
    	for(int i=lg[delta];i>=0;i--) 
    	if(f[i][u]!=f[i][v]) u = f[i][u],v = f[i][v];
    	return f[0][u];
    }
    
    inline bool cmp(int a,int b)
    {
    	return dfn[a] < dfn[b];
    }
    
    int qcnt=0;
    inline void gets(int op,int ed)
    {
    	qcnt++;
    	int lca = lca_(op,ed);
    	int step = 0,arcstep(0);
    	while(op != lca) sta[++step] = op,op = f[0][op];
    	sta[++step] = lca;
    	while(ed != lca) arc[++arcstep] = ed,ed = f[0][ed];
    	reverse(arc + 1,arc + 1 + arcstep);
    	printf("%d ",step + arcstep);
    	for(int i=1;i<=step;i++) printf("%d ",sta[i]);
    	for(int i=1;i<=arcstep;i++) printf("%d ",arc[i]);
    	printf("
    ");
    }
    
    signed  main()
    {
    	read(n);
    	read(m);
    	for(int i=2;i<=n;i++) lg[i] = lg[i >> 1] + 1;
    	for(int i=1,a,b;i<=m;i++)
    	{
    		read(a);
    		read(b);
    		add(a,b);
    		add(b,a);
    	}
    	
    	dfs(1,0);
    	for(int i=1;i<=lg[n];i++)
    		for(int j=1;j<=n;j++)
    		f[i][j] = f[i-1][f[i-1][j]];
    	if(top >= (n/3))
    	{
    		printf("2
    ");
    		for(int i=1;i<=(n/3);i++)
    		printf("%d ",leaf[i]);
    		return 0; 
    	}
    //	int son(0);
    //	for(int i=head[1];i;i=nxt[i]) son++;
    //	if(son == 1) leaf[++top] = 1;
    	leaf[++top] = 1;
    	if(top & 1) leaf[++top] = 1;
    	sort(leaf + 1,leaf + 1 + top,cmp);
    	
    	printf("1
    ");
    	for(int i=1;i<=top/2;i++)
    	{
    		int gol = i + top/2;
    		gets(leaf[i],leaf[gol]);
    	}
    	
    	for(int i=2;i<=n;i++)
    	{
    		if(qcnt < (n + 5)/6)
    		{
    			printf("%d %d
    ",1,i);
    			qcnt++;
    		}
    	}
    	return 0;
     }
    

    T4「PMOI-4」猜排列

    交互题。

    我们要求出 (l)(r) 之间的序列,先二分中点 (mid) 递归处理 (l)(mid)。我们已知 (mid) 的位置,可以直接用 (mid)([mid+1,r]) 这段区间做询问一,然后这样就做完了。

    #include<bits/stdc++.h>
    
    using namespace std;
    
    //#define int long long
    #define pb push_back
    
    template<typename _T>
    inline void read(_T &x)
    {
    	x=0;char s=getchar();int f=1;
    	while(s<'0'||s>'9') {f=1;if(s=='-')f=-1;s=getchar();}
    	while('0'<=s&&s<='9'){x=(x<<3)+(x<<1)+s-'0';s=getchar();}
    	x*=f;
    }
    
    const int np = 5e4 + 5;
    
    int a[np];
    int bit[20][np];
    int xx[np],yy[np];
    int aux[np],arc[np];
    //vector<>
    int n,m1,m2,m3;
    inline void solve4()
    {
    	int l(0);
    //		printf("? 4 3 ");
    	cout<<"? "<<4<<" ";
    	for(int i=1;i<=4;i++)cout<<i<<" ";// printf("%lld ",i);
    	cout<<"3"<<endl;
    //		printf("4
    ");
    //		fflush(stdout);
    //		read(l);
    //		scanf("%lld",&l);
    	read(l);
    	for(int i=1;i<=l;i++) read(xx[i]),yy[xx[i]]=1;
    	int top = 0;
    	for(int i=1;i<=n;i++)
    	{
    		if(yy[i] == 0)aux[++top] = i;
    	}
    	for(int i=1;i<=2;i++)
    	{
    		for(int q=1;q<=2;q++)
    		{
    			int ams;
    			printf("! %d %d
    ",xx[q],aux[i]);
    			fflush(stdout);
    //			read(ams);
    			scanf("%d",&ams);
    			if(ams)
    			{
    				a[aux[i]] = 2;
    				arc[2] = aux[i];
    				a[xx[q]] = 3;
    				arc[3] = xx[q];
    				if(i == 1) a[aux[i + 1]] = 1,arc[1] = aux[i + 1];
    				if(i == 2) a[aux[i - 1]] = 1,arc[1] = aux[i - 1];
    				if(q == 1) a[xx[q + 1]] = 4,arc[4] = xx[q + 1];
    				if(q == 2) a[xx[q - 1]] = 4,arc[4] = xx[q - 1];
    				printf("A ");
    				for(int j=1;j<=3;j++) printf("%d ",a[j]);
    				printf("%d",a[4]);
    				fflush(stdout);
    				return ;
    			}
    		}
    	}	
    }
    
    inline void solve(int dep,int l,int r,vector<int> vec) // [l,r] ºÍÕâ¸öÇø¼äÄÚµÄÊý 
    {
    	int mid = l + r >> 1,lim(0);
    	vector<int> nxt;
    	if(r-l+1==4) 
    	{
    		printf("? 4 ");
    		int op = -1;
    		for(auto i:vec) printf("%d ",i),bit[dep][i] += 1;
    		printf("3
    ");
    		fflush(stdout);
    		read(l);
    		for(int i=0;i<l;i++) read(aux[i]),bit[dep][aux[i]] += 1;
    		for(int i=1;i<=n;i++) if(bit[dep][i] == 1) xx[++op] = i;
    		for(int i=0;i<=op;i++)
    		{
    			for(int j=0,qans;j<l;j++)
    			{
    				printf("! %d %d
    ",aux[j],xx[i]);
    				fflush(stdout);
    				read(qans);
    				if(qans)
    				{
    					a[xx[i]] = 2;
    					a[aux[j]] = 3;
    					arc[2] = xx[i];
    					arc[3] = aux[j];
    					a[xx[i ^ 1]] = 1;
    					arc[1] = xx[i ^ 1];
    					a[aux[j ^ 1]] = 4;
    					arc[4] = aux[j ^ 1];
    					return;
    				}
    			}
    		}
    	}
    	if(l == r)
    	{
    		for(auto i:vec)a[i] = l,arc[l] = i;
    		return;
    	}
    	printf("? %d ",r-l+1);
    	for(auto i:vec) printf("%d ",i),bit[dep][i] = 1;
    	printf("%d
    ",mid + 1);
    	fflush(stdout);
    	read(lim);
    	for(int i=1,x;i<=lim;i++) read(x),bit[dep][x] += 1;
    	for(int i=1;i<=n;i++) if(bit[dep][i] == 1) nxt.pb(i);
    	solve(dep + 1,l,mid,nxt);
    	for(int i=1,qans;i<=n;i++)
    	{
    		if(bit[dep][i] == 2)
    		{
    			printf("! %d %d
    ",i,arc[mid]);//ax > ay
    			fflush(stdout);
    			read(qans);
    			if(!qans) a[i] = 2 * mid;
    			else a[i] = mid + qans;
    			arc[a[i]] = i;
    		}
    	}
    	return ;
    }
    
    inline void kkk(int l,int r)
    {
    	printf("%d %d
    ",l,r);
    	if(l == r) return;
    	int mid = l + r >> 1;
    	kkk(l,mid);
    	
    }
    
    
    
    signed  main()
    {
    	
    //	kkk(1,5e2);
    	scanf("%d%d%d%d",&n,&m1,&m2,&m3);
    	if(n == 4)
    	{
    		solve4();
    		return 0;
    	 } 
    	vector<int> q;
    	for(int i=1;i<=n;i++) q.pb(i);
    	solve(1,1,n,q);
    	printf("A ");
    	for(int i=1;i<=n;i++)
    	printf("%d ",a[i]);
    	fflush(stdout);	
     }
    
    

    补完一场 div2。

  • 相关阅读:
    506. 相对排名 Relative Ranks
    500. 单词是否在键盘上的同一行 Keyboard Row
    openstack live migration性能分析
    libvirt/qemu特性之numa
    nova Scheduling 配置
    Specify compute hosts with SSDs
    nova conductor
    osprofiler
    watcher
    stacktach和ceilometer
  • 原文地址:https://www.cnblogs.com/-Iris-/p/15340332.html
Copyright © 2011-2022 走看看