2016ACM/ICPC亚洲区沈阳站-重现赛

C.Recursive sequence

求ans(x),ans(1)=a,ans(2)=b,ans(n)=ans(n-2)*2+ans(n-1)+n^4

如果直接就去解。。。很难,毕竟不是那种可以直接化成矩阵的格式,我们也因为这个被卡很长时间

事实上可以把这道式子化成几个基本元素的格式,然后就容易组合了,比如ans(n-2)*2+ans(n-1)+(n-1)^4+4*(n-1)^3+6*(n-1)^2+4*(n-1)^1+1

包含了所有的基本组成形式,化绝对为相对,并且除了一个n-2其他都是n-1

然后就是矩阵乘时间了

#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cmath>
#include <iostream>
#include <cstring>

using namespace std;

typedef long long int ll;
const ll mod = 2147493647;

//定义矩阵乘法
struct matrix{
    ll arr[7][7];
    matrix operator*(matrix b){
        matrix ans;
        ll tmp;
        for(int i=0; i<7; i++)
            for(int j=0; j<7; j++){
                ans.arr[i][j] = 0;
                for(int k=0; k<7; k++){
                    tmp = (arr[i][k]*b.arr[k][j])%mod;
                    ans.arr[i][j] = (ans.arr[i][j] + tmp)%mod;
                }
            }
        return ans;
    }
};

//矩阵快速幂
matrix quick_pow(matrix a,ll N){
    matrix ans;
    memset(ans.arr,0,sizeof(ans.arr));
    for(int i=0; i<7; i++)
        ans.arr[i][i] = 1;
    while(N){
        if(N&1)
            ans = ans*a;
        a = a*a;
        N /= 2;;
    }
    return ans;
}

int main(){

    matrix a;
    memset(a.arr,0,sizeof(a.arr));
    a.arr[0][1] = 1;
    a.arr[1][1] = a.arr[1][2] = a.arr[1][6] = 1;
    a.arr[2][2] = a.arr[2][6] = 1;
    a.arr[1][0] = 2; a.arr[1][3] = a.arr[1][5] = a.arr[2][3] = a.arr[2][5] = 4;
    a.arr[1][4] = a.arr[2][4] = 6;
    a.arr[3][3] = a.arr[4][4] = a.arr[5][5] = a.arr[6][6] = 1;
    a.arr[3][6] = a.arr[4][6] = a.arr[5][6] = 1;
    a.arr[3][4] = a.arr[3][5] = 3;
    a.arr[4][5] = 2;
    int T;
    scanf("%d",&T);
    ll N,aa,bb;
    while(T--){
        scanf("%I64d %I64d %I64d",&N,&aa,&bb);
        if(N==1)
            printf("%I64d\n",aa);
        else if(N==2)
            printf("%I64d\n",bb);
        else{
            matrix ans = quick_pow(a,N-2);
            ll ANS = 0;
            ANS = (ANS+ans.arr[1][0]*aa)%mod;
            ANS = (ANS+ans.arr[1][1]*bb)%mod;
            ANS = (ANS+ans.arr[1][2]*16)%mod;
            ANS = (ANS+ans.arr[1][3]*8)%mod;
            ANS = (ANS+ans.arr[1][4]*4)%mod;
            ANS = (ANS+ans.arr[1][5]*2)%mod;
            ANS = (ANS+ans.arr[1][6]*1)%mod;
            printf("%I64d\n",ANS);
        }
    }
    return 0;
}

G.Do not pour out

注:我不会在电脑写希腊字符,西塔会写成0-

有直径2,高度2的圆柱体杯子,装d高度的水,把杯子倾倒至水正好不倒出,水面碰着杯沿,问此时水面面积

d==0时S=0,样例给出

d>=1时,水面椭圆是宽径为1,长径为2tan0-的椭圆,根据面积公式S=pi*length*width=pi/cos0-出解

0<d<1时,水面被杯底截断,只能用积分做。

把下述直线右边当做水的截面,一个个积分(岂可修!这么简单!为什么比赛时没想到呢!哎,都怪我被体积蒙蔽了)

V=(0<=y<=2)∫S0dy

S0=pi-a+k*1sina

cosa=k/1

k+1=ytan0-

V=(0<=y<=2)∫S0dy

=(0<=y<=2)∫pi-a+cosasinady

=(pi<=y<=a1)1/tan0-*∫(pi-a+cosasina)(-sina)da

a1=arccos(2tan0--1)

手动转换和确定值间太费时了,还是二分把,反正数据量也不是很多,答案是S=s0/sin0-

/*--------------------------------------------
 * File Name: HDU 5954
 * Author: Danliwoo
 * Mail: [email protected]
 * Created Time: 2016-11-01 22:22:15
--------------------------------------------*/

#include <bits/stdc++.h>
using namespace std;
double Pi = acos(-1.0);
double eps = 1e-100;
double tran = 180/Pi;
double vd;
double V(double a) {
    return Pi*cos(a) - a*cos(a) + sin(a) - pow(sin(a), 3)/3;
}
double get(double theta) {
    double a1 = acos(2*tan(theta)-1);
    double v = (V(a1) - V(Pi))/tan(theta);
    return v;
}
bool eq(double x, double y) {
    return fabs(x-y) < eps;
}
double find(double l, double r) {
    int cnt = 200;
    if(eq(get(l), vd)) return l;
    while(cnt--) {
        double mid = (l+r) / 2;
        double gd = get(mid);
        if(eq(gd, vd)) return mid;
        if(gd > vd) r = mid;
        else l = mid;
    }
    return l;
}
int main() {
    int T;
    scanf("%d", &T);
    while(T--) {
        double d;
        scanf("%lf", &d);
        vd = d * Pi;
        if(eq(d, 0)) {
            printf("0.00000\n");
            continue;
        }
        if(d - 1 > 0) {
            double theta = atan(2.0-d);
            double ans = Pi/cos(theta);
        //  printf("d>1 theta = %.5f\n", theta*tran);
            printf("%.5f\n", ans);
            continue;
        }
        double theta = find(eps, Pi/4);
        double a1 = acos(2 * tan(theta) - 1);
        double S1 = Pi - a1 + cos(a1) * sin(a1);
        double ans = S1 / sin(theta);
        printf("%.5f\n", ans);
    }
    return 0;
}

H.Guessing the Dice Roll

n个人给出长度为l,互不相同的猜测序列,每次用色子<只有这6个元素:1,2,3,4,5,6>确定添加到旧序列末尾的元素,谁的序列与序列的后缀相同就赢,问每人的胜利概率

直接就是AC自动机上。。。但是到了这一步就不知道如何转成矩阵来高斯消元

后面才发现应该以主串(色子投出的序列)为分配概率的依据而不是以子串(猜测序列)为分配概率的依据

这样就理解了为什么从根出发,概率是1/实边条数,不是1/实边权值和

非根结点转移到下一层时,概率按照正常的1/6来计算,因为到了这步回溯也算在概率里

非叶子结点(就是某人胜利的点)回溯到根的下一层时,要再乘从根出发到对应点的概率

此外数组的第1维是目的点,第2位才是出发点,因为方程式的意义是从不同点一定概率到达本点的总和

#include <bits/stdc++.h>

using namespace std;
typedef double db;
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
const db eps=1e-6;
const int N=110;
const int M=100010;
#define lson l, m, rt << 1
#define rson m + 1, r, rt << 1 | 1
#define CLR(a, b) memset(a, b, sizeof(a))

struct trie {
    int sz,val[N],fail[N],tr[N][6];
    void init() {
        sz=0;
        memset(tr,0,sizeof(tr));
        memset(val,0,sizeof(val));
        memset(fail,0,sizeof(fail));
    }
    int trie_insert(int *ch) {
        int w=0;
        while (*ch!=-1&&tr[w][*ch]) w=tr[w][*ch],ch++;
        while (*ch!=-1) tr[w][*ch]=++sz,ch++,w=sz;
        val[w]=1;return w;
    }
    void trie_build() {
        queue<int>Q;
        for (int i=0;i<6;i++)
        if (tr[0][i]) Q.push(tr[0][i]);
        while (!Q.empty()) {
            int now=Q.front();Q.pop();
            if (val[now]) continue ;
            for (int i=0;i<6;i++)
            if (tr[now][i]) {
                fail[tr[now][i]]=tr[fail[now]][i];
                Q.push(tr[now][i]);
            } else tr[now][i]=tr[fail[now]][i];
        }
    }
}AC;
double p[N][N];
int gauss(int n) {
    int i,j,k,mxi;
    db h;
    for (i=1;i<=n;i++) {
        mxi=i;
        for (j=i;j<=n;j++)
        if (fabs(p[j][i])>fabs(p[mxi][i])) mxi=j;
        if (fabs(p[mxi][i])<eps) return 0;
        if (mxi!=i) {
            for (j=i;j<=n+1;j++) swap(p[i][j],p[mxi][j]);
        }
        h=p[i][i];
        for (j=i;j<=n+1;j++) p[i][j]/=h;
        for (j=1;j<=n;j++)
        if (j!=i) {
            h=-p[j][i]/p[i][i];
            for (k=i;k<=n+1;k++) p[j][k]+=h*p[i][k];
        }
    }
    return 1;
}
int s[1000];
int ans[1000];
int main() {
    int t,n,l;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&n,&l);
        AC.init();
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<l;j++)
            {
                scanf("%d",s+j);s[j]--;
            }
            s[l]=-1;
            ans[i]=AC.trie_insert(s);
        }
        AC.trie_build();
        for(int i=0;i<=AC.sz;i++)
        {
            s[i]=0;
            for(int j=0;j<6;j++)if(AC.tr[i][j])s[i]++;
        }
        memset(p,0,sizeof(p));
        for(int i=1;i<=AC.sz;i++)p[i][i]=1.0;
        for(int i=0;i<6;i++)if(AC.tr[0][i])p[AC.tr[0][i]][AC.sz+1]+=1.0/s[0];//从根部出发,由于是按主串算的,要均分
        for(int i=1;i<=AC.sz;i++)
        {
            for(int j=0;j<6;j++)if(AC.tr[i][j])p[AC.tr[i][j]][i]-=1.0/6.0;
            if(s[i]!=6 && !AC.val[i])//i结点是非叶子且能回溯到边的
            {
                for(int k=0;k<6;k++)
                {
                    if(AC.tr[0][k])p[AC.tr[0][k]][i]-=1.0*(6-s[i])/6.0/s[0];
                }
            }
        }
        gauss(AC.sz);
        for(int i=0;i<n;i++)printf("%.6f%c",p[ans[i]][AC.sz+1],i==n-1?‘\n‘:‘ ‘);
    }getchar();getchar();
    return 0;
}

时间: 2024-10-12 14:49:34

2016ACM/ICPC亚洲区沈阳站-重现赛的相关文章

hdu5512 Pagodas(2015ACM/ICPC亚洲区沈阳站-重现赛(感谢东北大学) )

Pagodas Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 14 Accepted Submission(s): 13 Problem Description n pagodas were standing erect in Hong Jue Si between the Niushou Mountain and the Yuntai M

2017ACM/ICPC亚洲区沈阳站-重现赛(感谢东北大学)HDU6225.Little Boxes-大数加法

整理代码... Little Boxes Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)Total Submission(s): 2304    Accepted Submission(s): 818 Problem Description Little boxes on the hillside.Little boxes made of ticky-tacky.Littl

2016ACM/ICPC亚洲区大连站-重现赛

题目链接:http://acm.hdu.edu.cn/search.php?field=problem&key=2016ACM%2FICPC%D1%C7%D6%DE%C7%F8%B4%F3%C1%AC%D5%BE-%D6%D8%CF%D6%C8%FC%A3%A8%B8%D0%D0%BB%B4%F3%C1%AC%BA%A3%CA%C2%B4%F3%D1%A7%A3%A9&source=1&searchmode=source A.染色乱搞. 1 #include <bits/st

2015ACM/ICPC亚洲区沈阳站-重现赛 1004 Pagodas

Problem Description: n pagodas were standing erect in Hong Jue Si between the Niushou Mountain and the Yuntai Mountain, labelled from 1 to n. However, only two of them (labelled aand b, where 1≤a≠b≤n) withstood the test of time. Two monks, Yuwgna and

hdu 5510 Bazinga (kmp+dfs剪枝) 2015ACM/ICPC亚洲区沈阳站-重现赛(感谢东北大学)

废话: 这道题很是花了我一番功夫.首先,我不会kmp算法,还专门学了一下这个算法.其次,即使会用kmp,但是如果暴力枚举的话,还是毫无疑问会爆掉.因此在dfs的基础上加上两次剪枝解决了这道题. 题意: 我没有读题,只是队友给我解释了题意,然后我根据题意写的题. 大概意思是给n个字符串,从上到下依次标记为1——n,寻找一个标记最大的串,要求这个串满足:标记比它小的串中至少有一个不是它的子串. 输入: 第一行输入一个整型t,表示共有t组数据. 每组数据首行一个整型n,表示有n个串. 接下来n行,每行

2016ACM/ICPC亚洲区大连站-重现赛(感谢大连海事大学)(6/10)

1001题意:n个人,给m对敌对关系,X个好人,Y个坏人.现在问你是否每个人都是要么是好人,要么是坏人. 先看看与X,Y个人有联通的人是否有矛盾,没有矛盾的话咋就继续遍历那些不确定的人关系,随便取一个数3,与其相连的就是4,间隔就要相同,dfs搜过去就可以判断了 #include<bits/stdc++.h> using namespace std; #pragma comment(linker, "/STACK:102400000,102400000") #define

【hdu 5521】【 2015ACM/ICPC亚洲区沈阳站重现赛】Meeting 题意&题解&代码

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5521 题意: 输入:输入n表示有n个点,输入m表示有m个点集. 接下来m行信息,每行先输入一个t表示这个点集中任意两点费时为t,再输入一个s,表示有s个点在这个点集中,接下来s个数表示这些数在这个点集之中. 现在有两个人,其中一个人住在点1,另一个人住在点n,如果两个人要见面,同时出发,可以走走停停,问需要最少时间是多少,有哪几个点能被当成见面点. 题解: 我们发现这道题如果建好图之后就直接是一个

【hdu 5510】【2015ACM/ICPC亚洲区沈阳站-重现赛 】Bazinga 题意&题解&代码(C++)

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5510 题意: 给出n个字符串,求下标最大的字符串,存在下标小于它的字符串中有字符串不是他的子串. 题解: 首先能想到kmp+n^2暴力匹配,但是感觉会超时,因此我们需要加一些剪枝,水题,不要被他的数据范围吓到.. 代码: #include<iostream> #include<algorithm> #include<stdio.h> #include<string.

HDU 5950 Recursive sequence 【递推+矩阵快速幂】 (2016ACM/ICPC亚洲区沈阳站)

Recursive sequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 249    Accepted Submission(s): 140 Problem Description Farmer John likes to play mathematics games with his N cows. Recently, t