51nod 算法马拉松35(A-D)

挺好玩的一场比赛。

链接

A

打表,打到\(2e4\)左右会发现有一个长度\(104\)的循环节。

#include<bits/stdc++.h>
using namespace std;
int col[5010][5010];
int dx[4] = {1,0,-1,0},dy[4] = {0,1,0,-1};
long long n,tem=0;

int main()
{
    cin >> n;
    int x=0,y=0,d=0;
    while(tem<n){
        ++tem;
        x = x+dx[d], y = y+dy[d];
        if(!col[x+2500][y+2500])d++;
        else d--;
        d+=4;d%=4;
        col[x+2500][y+2500]^=1;
        if(tem>=15447 && (n-tem)%104==0){
            long long d2 = (n-tem)/104;
            cout << (long long)x - 2ll*d2 << " " << (long long)y - 2ll*d2 << endl;
            return 0;
        }
    }
    cout << x << " " << y << endl;
}

B

答案是\(\sum _i \text{i步之后仍然没有结束的概率}\)。这个是一个等比数列。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod = 1e9+7;
inline int add(int a,int b){a+=b;return a>=mod?a-mod:a;}
inline int sub(int a,int b){a-=b;return a<0?a+mod:a;}
inline int mul(int a,int b){return 1ll*a*b%mod;}
inline int qpow(int a,int b){int ret=1;for(;b;b>>=1,a=mul(a,a))if(b&1)ret=mul(ret,a);return ret;}
/* math */
const int N = 5e6+5;
int p[N],n,a,b,c;

int main()
{
    cin >> n ;
    cin >> p[1] >> a >> b >> c;
    for(int i=2;i<=n;i++)p[i] = add(c,add(mul(b,p[i-1]), mul(mul(p[i-1],p[i-1]),a)));
    for(int i=2;i<n;i++)p[n*2-i]=p[i];
    int p2 = 1, totp = 0;
    for(int i=1;i<2*n-1;i++){
        // cout << p[i] << " " ;
        totp = add(totp, mul(p2, sub(1,p[i])));
        p2 = mul(p2, sub(1,p[i]));
    }
    int ans = totp;
    ans = mul(totp,qpow(sub(1,p2),mod-2));
    cout << ans << endl;
}

C

分析一下会发现一个条边有贡献当且仅当两端子树都有一个点被选择了。

相当于子树内的点是一种颜色,子树外是另外一种。

维护连续颜色段,启发式合并就行了。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod = 1e9+7;
inline int add(int a,int b){a+=b;return a>=mod?a-mod:a;}
inline int sub(int a,int b){a-=b;return a<0?a+mod:a;}
inline int mul(int a,int b){return 1ll*a*b%mod;}
inline int qpow(int a,int b){int ret=1;for(;b;b>>=1,a=mul(a,a))if(b&1)ret=mul(ret,a);return ret;}
/* math */
int n;
const int N = 2e5+5;
int hed[N],to[N],nxt[N],cnt;
inline void adde(int u,int v){
    ++cnt;to[cnt]=v,nxt[cnt]=hed[u];hed[u]=cnt;
}
int id[N];
inline long long S(long long x){
    return x*(x+1)/2;
}
struct Node{
    long long ret;
    map<int,pair<int,int> > info;
    set<int> st;
    inline void ins(int x){
        st.insert(x);
        set<int>::iterator t = st.find(x), lst = t, nxt = t;
        int l=0,r=n+1;
        if(t!=st.begin())l = *(--lst);
        if(x!=*st.rbegin()) r = *(++nxt);
        ret -= S(r-l-1);
        int lft = x,rgt = x;
        if(l&&l==x-1){
            lft = info[l].first;
            ret-=S(l-lft+1);
        }
        if(r!=n+1&&r==x+1){
            rgt = info[r].second;
            ret-=S(rgt-r+1);
        }
        info[lft].second = rgt,info[rgt].first = lft;
        ret += S(rgt-lft+1);
        ret += S(r-1-x) + S(x-1-l);
    }
};
Node nd[N];
inline void mrg(Node &a,Node &b){
    set<int> :: iterator t = b.st.begin();
    for(;t!=b.st.end();++t){
        a.ins(*t);
    }
}
int sz[N];
long long ans = 0;
inline void dfs(int x,int pre){
    id[x] = x;
    nd[x].ret = S(n);
    nd[x].ins(x);
    sz[x] = 1;
    for(int i=hed[x];i;i=nxt[i]){
        int v = to[i];if(v==pre)continue;
        dfs(v,x);
        int ths = id[x], nxt = id[v];
        if(sz[x] < sz[v]){
            swap(ths,nxt);
        }
        mrg(nd[ths],nd[nxt]);
        id[x] = ths;
        sz[x] += sz[v];
    }
    if(pre)ans += S(n) - nd[id[x]].ret;
}

int main()
{
    cin >> n;
    for(int i=1;i<n;i++){
        int u,v;scanf("%d%d",&u,&v);
        adde(u,v),adde(v,u);
    }
    dfs(1,0);
    ans*=2;ans%=mod;
    int ss = S(n)%mod;
    cout << mul(ans, qpow(ss,mod-2)) << endl;
}

D

duliu ccz

把线段按照斜率 $>0 / <0 $ 分组。

先拆成四组询问,全部包含的线可以轻松扫描线。现在分别考虑与纵轴相交的和与y轴相交的。因为线段不交,这些点都在一段区间。拆式子用平衡树维护就行了。

然后写题时间 \(8:00 \to 15:00\)。我才不会告诉你我炸int调了3h

#include<bits/stdc++.h>
using namespace std;
typedef double db;
const int N = 4e5+5;
int n,m;
namespace sgt{
    #define lowbit(x) ((x)&(-x))
    db tag[2000002];int cnt,rt;
    inline void ins(int x,db s){
        for(;x<=2000000;x+=lowbit(x)){
            tag[x]+=s;
        }
    }
    inline db qry(int x){
        db ans = 0;
        while(x){
            ans+=tag[x];
            x-=lowbit(x);
        }return ans;
    }
    inline void clr(){
        for(int i=1;i<=2000000;i++)tag[i]=0;
    }
}
db sqr(db a){
    return a*a;
}
struct Line{
    int x1,y1,x2,y2;
    bool operator < (const Line b)const{
        return (y2-y1)/(x2-x1)<(b.y2-b.y1)/(b.x2-b.x1);
    }
    db cal(int id){return (db)(y2-y1)*(db)(id-x1)/(db)(x2-x1) + (db)y1;}
    db Sin(){return (db)sqrt((db)sqr(y2-y1)+sqr(x2-x1))/(db)(x2-x1);}
    db len(){return (db)sqrt((db)sqr(y2-y1)+sqr(x2-x1));}
}l[N],l2[N];

int D = 0;
namespace Bt{
    int curx;
    struct splaynode{
        int ch[2],fa;db x,sx,x2,sx2;
    }t[N];
    int null=0,root;
    inline bool son(int x){return t[t[x].fa].ch[1]==x;}
    inline bool isroot(int x){return t[t[x].fa].ch[1]!=x&&t[t[x].fa].ch[0]!=x;}
    inline void pushup(int x){
        t[x].sx=t[x].x+t[t[x].ch[0]].sx+t[t[x].ch[1]].sx;
        t[x].sx2=t[x].x2+t[t[x].ch[0]].sx2+t[t[x].ch[1]].sx2;
    }
    inline void rotate(int x){
        int f=t[x].fa,gf=t[t[x].fa].fa;
        bool a=son(x),b=son(x)^1;
        if(!isroot(f))t[gf].ch[son(f)]=x;
        t[x].fa=gf;
        t[f].ch[a]=t[x].ch[b];t[t[x].ch[b]].fa=f;
        t[x].ch[b]=f;t[f].fa=x;
        pushup(f);pushup(x);//"pushup
    }inline void dfs(int x){
        if(!x)return ;
        dfs(t[x].ch[0]);
        cout <<'[' <<  x  << " " << l[x].cal(curx) << ']'<< " ,";
        dfs(t[x].ch[1]);
    }
    inline void print(){
        dfs(root);puts("");
    }
    inline void splay(int x){
        while(!isroot(x)){
            int f=t[x].fa;
            if(!isroot(f)){
                if(son(f)^son(x))rotate(x);
                else rotate(f);
            }
            rotate(x);
        }
        root=x;
    }
    inline void splay2(int x){
        while(t[x].fa!=root){
            int f=t[x].fa;
            if(t[f].fa!=root){
                if(son(f)^son(x))rotate(x);
                else rotate(f);
            }
            rotate(x);
        }
    }
    bool comp(int a,int b){
        return l[a].cal(curx)<l[b].cal(curx);
    }
    bool cmp2(int a,int b){
        int d = curx - l[a].x1;
        int dy = l[a].y2-l[a].y1;
        int dx = l[a].x2-l[a].x1;
        int dt = b-l[a].y1;
        // cout << l[a].x1 << " " << l[a].x2 << " " << l[a].y1 << " " << l[a].y2 << " " << curx << ":" << b << "|||";
        // cout << d*dy << " " << dt*dx << endl;
        if(!D)return 1ll*d*dy<=1ll*dt*dx;
        else return 1ll*d*dy<1ll*dt*dx;
    }

    inline void del(int x){
        // cout << "Delete" << " " << x << endl;
        splay(x);
        if(!t[x].ch[0]){root=t[x].ch[1],t[root].fa=0;return;}
        if(!t[x].ch[1]){root=t[x].ch[0],t[root].fa=0;return;}
        int lft = t[x].ch[0];while(t[lft].ch[1])lft = t[lft].ch[1];
        int nxt = t[x].ch[1];while(t[nxt].ch[0])nxt = t[nxt].ch[0];
        splay(lft);
        splay2(nxt);
        t[nxt].ch[0]=null;
        pushup(nxt),pushup(lft);
        // print();
    }
    inline int query(int x,int yline){
        int id = root,ans = -1;
        while(id){
            bool side = cmp2(id,yline);
            if(side)ans = id;
            id = t[id].ch[side];
        }
        return ans;
    }

    inline void ins(int x){
        if(!root){root = x;}else{
            int lst = query(root,l[x].y1);
            if(lst==-1){t[x].ch[1]=root,t[root].fa=x;root=x,pushup(x);}
            else{
                splay(lst);
                int nxt = t[root].ch[1];
                if(!nxt){t[root].ch[1]=x,t[x].fa = root,pushup(root);}
                else{
                    while(t[nxt].ch[0])nxt=t[nxt].ch[0];
                    splay2(nxt);
                    t[nxt].ch[0]=x;t[x].fa=nxt;
                    pushup(nxt),pushup(root);
                }
            }
        }
        // cout << "ins" << x << endl;
        // print();
    }

    void clr(){
        for(int i=1;i<N;i++)t[i].ch[0]=t[i].ch[1]=t[i].fa=0,t[i].x=t[i].sx=t[i].x2=t[i].sx2=0;
        root=0;curx=-1e9;
    }
}

struct query{
    int x,y,id,d;
    query(int x=0,int y=0,int id=0,int d=0):x(x),y(y),id(id),d(d){}
    bool operator < (const query b)const{return x<b.x;}
}q[N<<3];
struct op{
    int x,y,id,d;
    op(int x=0,int y=0,int id=0,int d=0):x(x),y(y),id(id),d(d){}
    bool operator < (const op b)const{return x==b.x?(d<b.d):x<b.x;}
}o[N<<2];int tcnt;

inline void perform(int x){
    // cout << "per" << " " << o[x].id << " " << o[x].d << endl;
    Bt::curx = o[x].x;
    int id = o[x].id;
    // cout << id << " " << l[id].Cos() << endl;

    if(o[x].d==1){
        Bt::t[id].x = l[id].Sin();
        Bt::t[id].x2 = l[id].x1*l[id].Sin();
        Bt::pushup(id);
        Bt::ins(id);
    }else{
        Bt::del(id);
        if(!D)sgt::ins(l[id].y2,l[id].len());
    }
    // Bt::print();
    // puts("fin");
}
db ret[N];
inline void Query(int x){
    Bt::curx = q[x].x;
    // cout << "q" << D << ":;" << q[x].x << " " << q[x].y << "," << q[x].d << endl;
    // Bt::print();
    db ans1 = 0;
    if(!D){ans1 += sgt::qry(q[x].y);}

        // cout << ":" << ans1 << "..";
    int id1 = Bt::query(Bt::root,q[x].y);
    // cout << id1 << " " << ".." << endl;
    using namespace Bt;
    if(id1!=-1){
        Bt::splay(id1);
        int nxt = t[id1].ch[1];
        t[id1].ch[1]=0;pushup(id1);
        ans1+=(db)t[id1].sx*curx-t[id1].sx2;
        t[id1].ch[1]=nxt;pushup(id1);
    }
    // printf("%.6lf\n",ans1);
    ret[q[x].id] += (db)q[x].d*ans1;
    // Bt::print();
    // puts("--");
}
int _A[N],_B[N],_C[N],_D[N];

db tot = 0;
int main()
{
    cin >> n;
    for(int i=1;i<=n;i++){
        scanf("%d%d%d%d",&l2[i].x1,&l2[i].y1,&l2[i].x2,&l2[i].y2);
        if(l2[i].x1>l2[i].x2){
            swap(l2[i].x1,l2[i].x2), swap(l2[i].y1,l2[i].y2);
        }
        tot += sqrt((db)sqr(l2[i].x1-l2[i].x2)+(db)sqr(l2[i].y1-l2[i].y2));
    }
    sort(l2+1,l2+n+1);
    cin >> m;
//-----------------------------
    D=0;
    sgt::clr();Bt::clr();Bt::curx=-1e9;
    for(int i=1;i<=m;i++){
        int a,b,c,d;
        scanf("%d%d%d%d",&a,&b,&c,&d);
        _A[i]=a,_B[i]=b,_C[i]=c,_D[i]=d;
        q[i*4-3] = query(a,b,i,1);
        q[i*4-2] = query(c,d,i,1);
        q[i*4-1] = query(a,d,i,-1);
        q[i*4-0] = query(c,b,i,-1);
    }
    // cout << "???" << endl;
    tcnt=0;for(int i=1;i<=n;i++){
        l[i]=l2[i];
        if(l2[i].y1 <= l2[i].y2){
            o[++tcnt] = op(l[i].x1,l[i].y1,i,1);
            o[++tcnt] = op(l[i].x2,l[i].y2,i,-1);
        }
    }
    sort(q+1,q+m*4+1);sort(o+1,o+tcnt+1);
    int tar = 1;
    for(int d=1;d<=m*4;d++){
        while(tar<=tcnt && o[tar].x <= q[d].x){
            perform(tar);tar++;
        }Query(d);
    }
    /////
    D=1;
    sgt::clr();Bt::clr();Bt::curx=-1e9;
    for(int i=1;i<=m*4;i++)swap(q[i].x,q[i].y);
    tcnt=0;for(int i=1;i<=n;i++){
        l[i]=l2[i];
        swap(l[i].x1,l[i].y1);
        swap(l[i].x2,l[i].y2);
        if(l2[i].y1 <= l2[i].y2){
            o[++tcnt] = op(l[i].x1,l[i].y1,i,1);
            o[++tcnt] = op(l[i].x2,l[i].y2,i,-1);
        }
    }
    sort(q+1,q+m*4+1);sort(o+1,o+tcnt+1);
    tar = 1;
    for(int d=1;d<=m*4;d++){
        while(tar<=tcnt && o[tar].x <= q[d].x){
            perform(tar);tar++;
        }Query(d);
    }
//----------------------------------------
    D=0;
    sgt::clr();Bt::clr();Bt::curx=-1e9;
    for(int i=1;i<=m;i++){
        int a=_A[i],b=_B[i],c=_C[i],d=_D[i];
        q[i*4-3] = query(-a,b,i,-1);
        q[i*4-2] = query(-c,d,i,-1);
        q[i*4-1] = query(-a,d,i,1);
        q[i*4-0] = query(-c,b,i,1);
    }
    tcnt=0;for(int i=1;i<=n;i++){
        l[i]=l2[i];
        if(l2[i].y1>l2[i].y2){
            l[i].x1=-l[i].x1,l[i].x2=-l[i].x2;
            swap(l[i].x1,l[i].x2),swap(l[i].y1,l[i].y2);
            o[++tcnt] = op(l[i].x1,l[i].y1,i,1);
            o[++tcnt] = op(l[i].x2,l[i].y2,i,-1);
        }
    }
    sort(q+1,q+m*4+1);sort(o+1,o+tcnt+1);
    tar = 1;
    for(int d=1;d<=m*4;d++){
        while(tar<=tcnt && o[tar].x <= q[d].x){
            perform(tar);tar++;
        }Query(d);
    }
    /* CUTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT */
    D=1;
    sgt::clr();Bt::clr();Bt::curx=-1e9;
    for(int i=1;i<=m*4;i++)swap(q[i].x,q[i].y);
    tcnt=0;for(int i=1;i<=n;i++){
        l[i]=l2[i];
        if(l2[i].y1 > l2[i].y2){
            l[i].x1=-l[i].x1,l[i].x2=-l[i].x2;
            swap(l[i].x1,l[i].x2),swap(l[i].y1,l[i].y2);
            swap(l[i].x1,l[i].y1);swap(l[i].x2,l[i].y2);
            o[++tcnt] = op(l[i].x1,l[i].y1,i,1);
            o[++tcnt] = op(l[i].x2,l[i].y2,i,-1);
        }
    }
    sort(q+1,q+m*4+1);sort(o+1,o+tcnt+1);
    tar = 1;
    for(int d=1;d<=m*4;d++){
        while(tar<=tcnt && o[tar].x <= q[d].x){
            perform(tar);tar++;
        }Query(d);
    }
//-----------------------------
    for(int i=1;i<=m;i++){
        printf("%.8lf\n",1e-15+ret[i]/tot);
    }
}

原文地址:https://www.cnblogs.com/weiyanpeng/p/11623590.html

时间: 2024-08-06 20:10:03

51nod 算法马拉松35(A-D)的相关文章

51nod 算法马拉松35 E

有这样一段两两求最大公约数的程序CoGcd, int Gcd(int x, int y){ if(y == 0)return x; return Gcd(y, x % y); } void CoGcd(int m){ for(int i = 1; i <= m; i++) for(int j = 1; j <= m; j++) Gcd(i, j); } 给出m的值,进行t次询问,每次询问包含一对xi,yi.针对每次询问,输出整个程序执行过程当中,Gcd(xi, yi)被执行了多少次. 例如:\

51Nod 算法马拉松21(迎新年)

这次打算法马拉松是在星期五的晚上,发挥还算正常(废话,剩下的题都不会= =). 讲讲比赛经过吧. 8:00准时发题,拿到之后第一时间开始读. A配对,看上去像是二分图最大权匹配,一看范围吓傻了,先跳过读后面的题. B完全二叉树的方差,大概看了一遍,好神的样子,跳过. C多项式?好吧没学过FFT和NTT的我肯定不会,跳跳跳. D最大值,哎呦这函数什么破玩意儿,看不懂,跳跳跳. E B君的射击,卧槽毕克大人您出题就算了出这么一道码农题是要闹那样,跳跳跳. F那些年,我们一起讲的故事,卧槽这特么简直就

随便玩玩系列之一:SPOJ-RNG+51nod 算法马拉松17F+51nod 1034 骨牌覆盖v3

先说说前面的SPOJ-RNG吧,题意就是给n个数,x1,x2,...,xn 每次可以生成[-x1,x1]范围的浮点数,把n次这种操作生成的数之和加起来,为s,求s在[A,B]内的概率 连续形的概率,想象为一个n维长方体,有两个平面与这个几何图形相割,于是就变成了求面(体)积问题,一般要去重,n维区域系数:s^n/n!,至于区间问题,直接前缀之差搞定 然后就是悲催的算法马拉松17F题了...其实是道好题来的,只是出题人不知世界上还有这题,然后某大牛把思路理清后把答案直接搬了过来 经典的1*2骨牌覆

51Nod 算法马拉松15 记一次悲壮而又开心的骗分比赛

OwO 故事的起源大概是zcg前天发现51Nod晚上有场马拉松,然后他就很开心的过去打了 神奇的故事就开始了: 晚上的时候我当时貌似正在写线段树?然后看见zcg一脸激动告诉我第一题有九个点直接输出B就可以A.. 然后之后zcg以奇怪的二分方式发现了如何A掉第一题的第十个点(我记得貌似是什么第5000个数等于511? OwO 就这样没有任何思考含量全凭骗分黑科技过掉了第一题 OwO 然后zcg打开了第二题,发现第二题样例有点问题,然后就发了个帖子,直接去看第三题了 我去瞅了一眼,发现这不是gcd

51nod算法马拉松 contest7

A题 链接:http://www.51nod.com/contest/problem.html#!problemId=1417 推荐链接:http://blog.csdn.net/a837199685/article/details/45009337 设美女取得正面概率是p,反面就是(1-p),就是美女取一正一反和一反一正的概率相同,然后推出公式y=((a+b)/2+b)/(2*(a+b)); 1 #include<iostream> 2 #include<cstdio> 3 #i

51Nod 算法马拉松23 开黑记

惨啊--虽然开了半天黑,但是还是被dalao们踩了-- 第二次开黑,还是被卡在rank20了,我好菜啊--= = 写一写比赛经过吧-- 看到题之后习惯性都打开,A~D看上去似乎并没有什么思路,F应该是道数论题,看了E感觉有点意思,一看数据范围,咦怎么只有$50000$,再仔细看一看式子,手动分情况讨论之后得到一个结论-- 这题是水的线段树维护莫队啊= = 然后就开始码码码,由于一些脑残错误调了一会儿,然后就得到了这样的结果: 我坚信自己莫队的复杂度没错,然后就开始各种王逸松卡常,使用的卡常技巧包

51nod 算法马拉松4

http://www.51nod.com/contest/problemList.html#!contestId=9 D 装盒子 拓扑排序?

51NOD算法马拉松 最大值问题 离线预处理+set lower_bound

题目:http://www.51nod.com/contest/problem.html#!problemId=1349 题意:100000个数的序列,有100000次询问,每次问区间最大值大于等于k的区间有多少? 思路:一开始没看到"大于等于",想了很久也不会,原来看错题了.看错题害死人. 一般询问的问题,如果不能用线段树log(n)求出,那么就离线做. 首先将询问按从大到小排序,再将序列中的每个数排序,注意记录序号. 对于当前询问,每加进一个数,我需要找到它在加进的序列(按大小有序

51nod 算法马拉松4 D装盒子(网络流 / 二分图最优匹配)

装盒子 基准时间限制:1 秒 空间限制:131072 KB 分值: 160 有n个长方形盒子,第i个长度为Li,宽度为Wi,我们需要把他们套放.注意一个盒子只可以套入长和宽分别不小于它的盒子,并且一个盒子里最多只能直接装入另外一个盒子 (但是可以不断嵌套),例如1 * 1 可以套入2 * 1,而2 * 1再套入2 * 2.套入之后盒子占地面积是最外面盒子的占地面积.给定N个盒子大小,求最终最小的总占地面积. Input 第一行一个数N表示盒子的个数. 接下来N行,每行两个正整数,表示每个盒子的长