zoukankan      html  css  js  c++  java
  • Codeforces 989E A Trance of Nightfall 矩阵快速幂+DP

    题意:二维平面上右一点集(S),共(n)个元素,开始位于平面上任意点(P)(P)不一定属于(S),每次操作为选一条至少包含(S)中两个元素和当前位置(P)的直线,每条直线选取概率相同,同一直线上每个点(Q in S) 选取概率相同,(Q)次询问 包含两个元素(t,m) 即点(P)(t)共操作(m)次的最大概率

    打了场(CF) 结果(D)题死活调不出来 只能一大早来补题了

    可以想到记录(f[i][j][k])表示从点(i)到点(j)(k)步的概率 这个过程我们可以通过记录(2^x)的矩阵来存储

    之后可以发现对于一个询问(t,m) 我们可以通过矩阵的转移得到走(m-1)步的答案 之所以不能直接走(m)步是因为第一步的点P不一定在(S)内 分析一下就可以发现 一条线(l)上的点的概率就(frac {sum_{(i in S)}probility[i]}{sum_{(i in S)}1}) 对所有直线取个(max)就是答案了

    复杂度 (O((n + q) cdot n^2 cdot log m))

    #include<bits/stdc++.h>
    using namespace std;
    #define FO(x) {freopen(#x".in","r",stdin);freopen(#x".out","w",stdout);}
    #define pa pair<int,int>
    #define mod 1000000007
    #define ll long long
    #define mk make_pair
    #define pb push_back
    #define fi first
    #define se second
    #define cl(x) memset(x,0,sizeof x)
    #ifdef Devil_Gary
    #define bug(x) cout<<(#x)<<" "<<(x)<<endl
    #define debug(...) fprintf(stderr, __VA_ARGS__)
    #else
    #define bug(x)
    #define debug(...)
    #endif
    const int INF = 0x7fffffff;
    const int N=2e2+5;
    /*
    char *TT,*mo,but[(1<<15)+2];
    #define getchar() ((TT==mo&&(mo=(TT=but)+fread(but,1,1<<15,stdin),TT==mo))?-1:*TT++)//*/
    inline int read(){
        int x=0,rev=0,ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')rev=1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
        return rev?-x:x;
    }
    int n,flg,x[N],y[N];
    double ans,pro[N],tmp[N];
    vector<vector<int> > lines;
    struct matrix{
    	double g[N][N];
    	matrix operator * (const matrix&a){
    		matrix c;cl(c.g);
    		for(int i=0;i<n;i++)
    			for(int j=0;j<n;j++) 	
    				for(int k=0;k<n;k++)
    				c.g[i][j]+=g[i][k]*a.g[k][j];
    				return c;
    	}
    }f[15];
    pa fix(pa a){
    	if(a.fi==0) return mk(0,1);
    	if(a.se==0) return mk(1,0);
    	int d=__gcd(a.fi,a.se);
    	a.fi/=d,a.se/=d;
    	if(a.fi<0) a.fi*=-1,a.se*=-1;
    	return a;
    }
    void add(int p){
    	map<pa ,vector<int>>cnt;
    	for(int i=0;i<n;i++) if(i!=p){
    		int dx=x[i]-x[p],dy=y[i]-y[p];
    		cnt[fix(mk(dx,dy))].pb(i);
    	}
    	int sz=cnt.size();
    	for(auto u:cnt){
    		u.se.pb(p),flg=1;
    		for(auto v:u.se){
    			f[0].g[p][v]+=1.0/u.se.size()/sz;
    			if(v<p) flg=0;
    		}
    		if(flg) lines.pb(u.se);
    	}
    }
    int main(){
    #ifdef Devil_Gary
    	freopen("in.txt","r",stdin);
    #endif
    	n=read();
    	for(int i=0;i<n;i++) x[i]=read(),y[i]=read();
    	for(int i=0;i<n;i++) add(i);
    	for(int i=1;i<=14;i++)  f[i]=f[i-1]*f[i-1];
    	for(int Q=read();Q;Q--){
    		int t=read()-1,m=read()-1;
    		for(int i=0;i<n;i++) pro[i]=0;pro[t]=1.0; 
    		for(int i=0;i<=14;i++){
    			if(m&(1<<i)){
    				for(int j=0;j<n;j++) tmp[j]=pro[j],pro[j]=0;
    				for(int j=0;j<n;j++) for(int k=0;k<n;k++){
    					pro[j]+=tmp[k]*f[i].g[j][k]; 
    				}
    			}
    		}
    		ans=0;
    		for(auto line:lines){
    			double temp=0;
    			for(auto u:line) temp+=pro[u];
    			ans=max(ans,temp/line.size());
    		}
    		printf("%.12lf
    ",ans);
    	}
    }
    
    
    
  • 相关阅读:
    mysql 分列或取子串
    Excel “20200504”文本格式转化为时间格式
    Mysql清空数据表
    python 做词云图
    Pandas操作excel
    python中zip()函数的用法
    Excel技能提升
    JS 学习笔记
    元类理解与元类编程 《Python3网络爬虫开发》中第九章代理的使用代码Crawler中代码的理解
    关于选择器注意的点
  • 原文地址:https://www.cnblogs.com/devil-gary/p/9171771.html
Copyright © 2011-2022 走看看