zoukankan      html  css  js  c++  java
  • LOJ #2341. 「WC2018」即时战略 交互+LCT+随机化

    第一次做交互题,感觉挺有趣的.     

    对于链的部分,可以随机一个点拓展,直到拓展到该点为止.

    但是最坏情况下可能每次都要询问两次(每次左右端点都选错).  

    据说随机化情况下出错的次数大概为 $O( log n)$ 次.     

    对于树的部分最暴力的做法是从根节点开始询问,暴力拓展到叶子.        

    假设钦定一条从根节点向下延申的链,“拐点” 具有一定的单调性,所以可以在链上二分(即 splay 上二分)    

    code: 

    #include "rts.h"
    #include <bits/stdc++.h>  
    #define N 1000005 
    #define ll long long 
    #define lson s[x].ch[0] 
    #define rson s[x].ch[1]  
    
    using namespace std;  
    
    int vis[N],arr[N],sta[N];                   
    
    int ran(int l) { return (ll)rand()*rand()%l+1; }    
     
    struct data {
    	int ch[2],f,rev,l,r;  
    }s[N];  
    inline int get(int x) { return s[s[x].f].ch[1]==x; }       
    inline int isr(int x) { return s[s[x].f].ch[0]!=x&&s[s[x].f].ch[1]!=x; }     
    inline void pushup(int x) 
    {
    	s[x].l=s[x].r=x;  
    	if(lson) s[x].l=s[lson].l;  
    	if(rson) s[x].r=s[rson].r;  
    }
    inline void mark(int x) { s[x].rev^=1,swap(lson,rson),swap(s[x].l,s[x].r); }    
    inline void push(int x) 
    {
    	if(s[x].rev) 
    	{
    		if(lson) mark(lson);       
    		if(rson) mark(rson); 
    		s[x].rev^=1; 
    	}
    }
    void rotate(int x) 
    {
    	int old=s[x].f,fold=s[old].f,which=get(x);  
    	if(!isr(old)) 
    		s[fold].ch[s[fold].ch[1]==old]=x;     
    	s[old].ch[which]=s[x].ch[which^1];  
    	if(s[old].ch[which]) 
    		s[s[old].ch[which]].f=old;  
    	s[x].ch[which^1]=old,s[old].f=x,s[x].f=fold;  
    	pushup(old),pushup(x);  
    }
    void splay(int x) 
    {
    	int v=0,u=x,fa;  
    	for(sta[++v]=u;!isr(u);u=s[u].f) sta[++v]=s[u].f;     
    	for(;v;--v) push(sta[v]);   
    	for(u=s[u].f;(fa=s[x].f)!=u;rotate(x))  
    		if(s[fa].f!=u) 
    			rotate(get(fa)==get(x)?fa:x);   
    }
    void access(int x)  
    {
    	for(int y=0;x;y=x,x=s[x].f) 
    		splay(x),rson=y,pushup(x); 
    }
    void makert(int x) 
    {
    	access(x),splay(x),mark(x);  
    } 
    void link(int x,int y) { s[x].f=y; }   
    int getrt(int x) { while(!isr(x)) x=s[x].f; return x; } 
    void play(int n, int T, int dataType) 
    {
    	srand((unsigned)time(NULL));  
    	if(dataType==3) 
    	{            
    		int L=1,R=1;    
    		for(int i=2;i<=n;++i) arr[i]=i;      
    		random_shuffle(arr+2,arr+1+n);  
    		for(int i=2;i<=n;++i) 
    		{
    			int u=arr[i];       
    			if(vis[u]) continue;     
    			int p=explore(L,u);      
    			if(!vis[p]) 
    			{
    				vis[p]=1,L=p;
    				while(p!=u) p=explore(p,u),L=p,vis[p]=1;              
    			}   
    			else 
    			{
    				int p2=explore(R,u);    
    				vis[p2]=1,R=p2;   
    				while(p2!=u) p2=explore(p2,u),R=p2,vis[p2]=1; 
    			}
    		} 
    	}
    	else 
    	{
    		vis[1]=1,arr[1]=1; 
    		for(int i=2;i<=n;++i) arr[i]=i;  
    		random_shuffle(arr+2,arr+1+n);    
    		for(int i=2;i<=n;++i) 
    		{
    			int u=arr[i]; 
    			if(vis[u]) continue;    
    			int x=getrt(1),cn=0; 
    			while(1) 
    			{
    				push(x);       
    				int cur=explore(x,u);    
    				if(!vis[cur]) 
    				{
    					vis[cur]=1,link(cur,x),x=cur;       
    					while(cur!=u) 
    					{
    						cur=explore(cur,u);     
    						vis[cur]=1,link(cur,x),x=cur;  
    					}     
    					access(x); 
    					break;   
    				}   
    				if(cur==s[rson].l) x=rson;   
    				else if(cur==s[lson].r) x=lson;  
    				else x=getrt(cur);                 
    			}   
    		}
    	}
    }
    

      

  • 相关阅读:
    第五章 Internet协议
    第四章 地址解析协议
    Learn the shell
    Linux学习前的准备
    第三章 链路层
    第二章 Internet 地址结构
    后台数据导出为Excel
    C#开发客户端、JAVA和tomcat开发服务端
    Java基础
    C++学习笔记--(1)
  • 原文地址:https://www.cnblogs.com/guangheli/p/12936494.html
Copyright © 2011-2022 走看看