2012网赛金华赛区

来源:互联网 发布:c 高级编程第7版 pdf 编辑:程序博客网 时间:2024/05/01 14:47

hdu 4405 Aeroplane chess

期望dp..倒着推方便一些。 dp[i]记录从i到终点用的次数的期望, dp[0]为答案。


#include <cstring>#include <cstdio>#include <cmath>#include <algorithm>#include <vector>using namespace std;const int maxn=100000+123;double dp[maxn];int fly[maxn];const double pr=1.0/6.0;int main(){    int n, m;     while (~scanf("%d%d", &n, &m), n||m)    {        memset (fly, -1, sizeof(fly));        for (int i=0; i<m; ++i)        {            int a, b; scanf("%d%d", &a, &b);             fly[a]=b;        }        memset (dp, 0, sizeof(dp));        for (int i=n-1; i>=0; --i)        {            if(fly[i]==-1)            {                for (int j=1; j<=6; ++j)                    dp[i]+=dp[i+j]*pr;                dp[i]+=1.0;            }            else dp[i]=dp[fly[i]];            ///printf("%d %lf\n", i, dp[i]);        }        printf("%0.4lf\n", dp[0]);    }    return 0;}/*2 08 32 44 57 8*/


4407 Sum

容斥, 一开始没注意m=1000. 一直再考虑线段树什么的, 估计是最近做题做蒙圈子了。

后来发现每个操作是可以有O(10^3~10^4)的复杂度, 于是想到对每个op1先求出没改变前的结果, 再将之前所改变的位置计算进去就可以了,op2操作就可以用map直接覆盖原来的数值, 这样保证每个op1时更改的都是最新的操作, 在求某个区间未改变前的sum时, 可以跑个2^7的容斥。

#include <cstring>#include <cstdio>#include <map>#include <iostream>using namespace std;typedef long long ll;bool vis[400010], t[700];int p[1000],num, num1, ct;int a[400010];int pp[100];map<int, int> pos;void init(){    num = 0;    memset(t, false, sizeof(false));    for (int i = 2; i <= 650; ++i)    {        if(!t[i])        {            p[num++] =i;            for(int j = i; j <=650; j += i)                t[j] = true;        }    }    return ;}void ppp(int x ){    int i = 0, q = x;    while(i < num)    {        if(q % p[i] == 0)        {            pp[num1++] = p[i];            while(q % p[i] == 0)                q = q / p[i];        }        i++;    }    if(q>1)pp[num1++]=q;    return ;}bool check(int x){    for(int i = 0; i < num1; ++i)        if(x % pp[i] == 0) return false;    return true;}ll sum(ll s, ll t){    return (s+t)*(t-s+1)/2;}int main(){    int T;    scanf("%d", &T);    init();    while (T--)    {        int x, y, c, o, i, n, m, p;        long long ans = 0;        pos.clear();        scanf("%d%d", &n, &m);        for(i = 1; i <= n; ++i)            a[i] = i;        for(i = 0; i < m; ++i)        {            scanf("%d", &o);            if(o == 1)            {                ans = 0;                scanf("%d%d%d", &x, &y, &p);                num1 = 0;                ppp(p);                int limit=1<<num1;                ///printf("%d %d\n", limit, num1);                for (int j=0; j<limit; ++j)                {                    ll pro=1;                    int cnt=0;                    for (int sta=j, tt=0; sta; sta>>=1, tt++)                    {                        if(sta&1)pro*=pp[tt], cnt++;                    }                    if(cnt&1)ans-=sum((x+pro-1)/pro, y/pro)*(ll)pro;                    else ans+=sum((x+pro-1)/pro, y/pro)*(ll)pro;                    ///printf("sta=%d  %I64d \n", j, ans);                }                map<int, int>::iterator it;                for(it=pos.begin(); it!=pos.end(); ++it)                    if(it->first>=x && it->first<=y)                    {                        if(check(it->second)) ans+=it->second;                        if(check(it->first)) ans-=it->first;                    }                cout << ans << endl;            }            else if(o == 2)            {                int flag = 1;                scanf("%d%d", &x, &c);                pos[x]=c;            }        }    }    return 0;}/*103 32 2 31 1 3 41 2 3 615 32 13 1691 2 15 23101 2 12 231015 52 13 132 13 1691 2 15 31 2 15 3999991 1 15 13333360 31 1 60 301 2 60 301 2 59 3060 11 1 60 1400000 11 1 400000 1*/