zoukankan      html  css  js  c++  java
  • 第十四次考试

    鬼知道(cjx)从哪里扣的题目(特别是T2),感觉全是坑,T1卡精度,T2写压位高精才满分,T3机房的(dalao)们有(inf)种解法。。

    T1 拖拉机

    【题目描述】:
    啦啦啦,宇宙级帅锅(TYH)(没错就是陶一刀)又开着他心爱的拖拉机上学去了,由于他魅力四射,一路上遇到很多妹子,这些妹子都非要跟着他,他也只好勉为其难。一开始(TYH)的拖拉机速度为(1km/min),但妹子的体重实在不忍直视,以至于当他带上(i)个妹子以后,他的速度会降到(frac{1}{(i + 1)}km/min),例如当他带上(1)个妹子时,速度为(frac{1}{2})(2)个妹子时,速度为(frac{1}{3}),以此类推。
    (TYH)(RP)是如此的好,上天总是在他到达整数距离或整数时刻的时候让一个妹子出现。(TYH)想知道他多久才能到学校。
    【输入格式】:
    第一行两个正整数(n),(m),表示妹子的数量和(TYH)距离学校的距离。
    接下来(n + 1)行,每行有两种形式:

    1. (Dist) (x) 表示在距离到达 (x) (km)时出现一个妹子
    2. (Time) (x) 表示在时间到达 (x) (min)的时候出现一个妹子

    【输出格式】:
    一行一个数,表示(TYH)到达学校的时间,如果不能整除,直接输出整数部分。
    【样例输入】:

    2 20
    Time 3
    Dist 10
    

    【样例输出】:

    47
    

    【数据范围】:
    对于(30)%数据,(1) <= (n),(m) <= (50)
    对于(50)%数据,(1) <= (n),(m) <= (2000)
    对于(100)%数据,(1) <= (n),(m) <= (200000),(0) <= (x) <= (1e9)

    思路:

    直接模拟即可,判断属性分别为(Time)(Dist)的妹子被遇到的先后顺序,然后直接(pick) (up)就可以了。注意判断哪些在学校之后的妹子,直接甩了不要。。反正陶一刀女朋友够

    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    
    char s[5];
    
    const int MAXN = 200005;
    
    double ti[MAXN],di[MAXN];
    
    int main(){
        int n;double m;scanf("%d%lf",&n,&m);
        int t=0,d=0;
        for(int i=1;i<=n;++i){
            scanf("%s",s);
            if(s[0] == 'T'){
                double a;scanf("%lf",&a);
                ti[++t] = a;
            }
            else{
                double a;scanf("%lf",&a);
                if(a >= m) continue;
                di[++d] = a;
            }
        }
        sort(ti+1,ti+1+t);
        sort(di+1,di+1+d);
        if(ti[1] >= m){
            printf("%.0lf",m);
            return 0;
        }
        int h1=1;int h2=1;double ans = 1.0;
        double cost = 0.0;double DIS = 0.0;
        while(h1!=t+1 || h2!=d+1){1. 
            double v = 1/ans*1.0;
            if(DIS >= m) break;
            if((ti[h1] - cost < (di[h2]-DIS)/v && h1!=t+1) || h2 == d+1){
                DIS += (ti[h1]-cost)*v;
                cost = ti[h1];
                h1++;
                ans+=1.0;
                continue;
            }
            if((ti[h1] - cost > (di[h2]-DIS)/v && h2!=d+1) || h1 == t+1){
                cost += (di[h2]-DIS)/v;
                DIS = di[h2];
                h2++;
                ans+=1.0;
                continue;
            }
            if(ti[h1] - cost == (di[h2]-DIS)/v - cost && h2!=d+1 && h1!=t+1){
                cost = ti[h1];
                DIS = di[h2];
                h1++;h2++;ans+=2.0;
                continue;
            }
        }
        double v = 1/ans*1.0;
        cost += (m - DIS)/v;
        printf("%.0lf",floor(cost));
        return 0;
    }
    

    T2 序列操作

    【题面描述】:
    (CJJ)(SCOI2012)那道序列操作做吐了,于是他想出了一道简单的序列操作的题目自我安慰。
    有一个包含(n)个数序列的(A_i),她想找出两个非空的集合(S)(T)
    这两个集合要满足以下的条件:

    1. 两个集合中的元素都为整数,且都在([1,n]) 里,即(S_i)(T_i)([1,n])
    2. 对于集合(S)中任意一个元素(x),集合(T)中任意一个元素(y),满足(x < y)
    3. 对于大小分别为p, q的集合S与T,满足:
      (A[s_1]) (xor) (A[s_2]) (xor) (A[s_3]) ... (xor) (A[s_p]) =
      (A[t_1]) (and) (A[t_2]) (and) (A[t_3]) ... (and) (A[t_q])

    上式中的(xor)(and)分别表示位运算异或运算和与运算。
    (CJJ)想知道一共有多少对这样的集合((S,T)),既然你都来了,就帮忙一起算一下吧。
    【输入格式】:
    第一行,一个整数(n)
    第二行,(n)个整数,代表(A_i)
    【输出格式】:
    仅一行,表示最后的答案。
    【样例输入】:

    4   
    1 2 3 3  
    

    【样例输出】:

    4  
    

    【数据范围】:
    对于(30)%的数据, (1 <= n <= 10)
    对于(70)%的数据, (1 <= n <= 100)
    对于(100)%的数据,(1 <= n <= 1000, 0 <= ai < 1024)

    思路:

    这TM明明比序列操作还难好吗。表示当时题都没看懂:)
    (Dp),两个数相等就相当于两个数的(xor)(0)。设 (f[i][j][k=0..2])代表 处理到第 (i) 个数,如果 (k = 1)代表(and)值为(j),如果(k = 2)代表(xor) 值为 (j),如果(k = 0)则代表一个元素都没取。所以很容易得到方程:

    • (f[i][j][0] = f[i + 1][j][0])
    • (f[i])[(j) & (a_i)]([1]) = (f[i + 1][j][1] + f[i + 1][j][0] + f[i + 1][j) & (a_i)]([1])
    • (f[i][j) ^ (a_i2]) = (f[i + 1][j][1] + f[i + 1][j][2] + f[i + 1][j) ^ (a_i][2]);

    最后(f[1][0][2])就是答案, 复杂度为(O(n * 1024 * 3))
    (DP)还可以分开用(f[i][j])(g[i][j])表示前(i)(xor)值为(j),后(i)(and)值为(j)的方案数, 随后枚举分界点(k)来求总方案数。复杂度(O(n * 1024 * 3))
    但是。。。。。。

    没错你没有看错,没加高精度只有70dpts!!!

    于是这道题还要愉快地加上高精度。。。
    本人高精度写得丑,用了一下(jacktang)

    #include<cstring>
    #include<algorithm>
    #include<cstdio>
    #include<cmath>
    #define LL long long
    #define gch getchar
    #define pch putchar
    using namespace std;
    template <class X> inline void read(X &x){
        x=0;char ch=gch();X f=1;
        while(ch>'9' || ch<'0') {if(ch=='-') f=-1;ch=gch();}
        while(ch>='0' && ch<='9') {x=(x<<1)+(x<<3)+ch-48;ch=gch();}
        x*=f;
    }
    const int MAXN=1000+5;
    LL n,a[MAXN];
    
    struct huge{
        #define N_huge 110
        #define base 100000000
        static char s[N_huge*10];
        typedef long long value;
        value a[N_huge];int len;
        void clear(){len=1;a[len]=0;}
        huge(){clear();}
        huge(value x){*this=x;}
        huge(char s[]){this->str(s);}
        huge operator =(const huge &b){
            len=b.len;for (int i=1;i<=len;++i)a[i]=b.a[i]; return *this;
        }
        huge operator +(const huge &b){
            int L=len>b.len?len:b.len;huge tmp;
            for (int i=1;i<=L+1;++i)tmp.a[i]=0;
            for (int i=1;i<=L;++i){
                if (i>len)tmp.a[i]+=b.a[i];
                else if (i>b.len)tmp.a[i]+=a[i];
                else {
                    tmp.a[i]+=a[i]+b.a[i];
                    if (tmp.a[i]>=base){
                        tmp.a[i]-=base;++tmp.a[i+1];
                    }
                }
            }
            if (tmp.a[L+1])tmp.len=L+1;
                else tmp.len=L;
            return tmp;
        }
        huge operator -(huge b){
            int L=len>b.len?len:b.len;huge tmp;
            for (int i=1;i<=L+1;++i)tmp.a[i]=0;
            for (int i=1;i<=L;++i){
                if (i>b.len)b.a[i]=0;
                tmp.a[i]+=a[i]-b.a[i];
                if (tmp.a[i]<0){
                    tmp.a[i]+=base;--tmp.a[i+1];
                }
            }
            while (L>1&&!tmp.a[L])--L;
            tmp.len=L;
            return tmp;
        }
        huge operator *(const huge &b)const{
            int L=len+b.len;huge tmp;
            for (int i=1;i<=L;++i)tmp.a[i]=0;
            for (int i=1;i<=len;++i)
                for (int j=1;j<=b.len;++j){
                    tmp.a[i+j-1]+=a[i]*b.a[j];
                    if (tmp.a[i+j-1]>=base){
                        tmp.a[i+j]+=tmp.a[i+j-1]/base;
                        tmp.a[i+j-1]%=base;
                    }
                }
            tmp.len=len+b.len;
            while (tmp.len>1&&!tmp.a[tmp.len])--tmp.len;
            return tmp;
        }
        /*huge operator *(const huge &b){
            int L=len+b.len;huge tmp;
            for (int i=1;i<=L;++i)tmp.a[i]=0;
            for (int i=1;i<=len;++i)
                for (int j=1;j<=b.len;++j)
                    tmp.a[i+j-1]+=a[i]*b.a[j];
            tmp.len=len+b.len;
            for (int i=1;i<tmp.len;++i)
                if (tmp.a[i]>=base){
                    tmp.a[i+1]+=tmp.a[i]/base;
                    tmp.a[i]%=base;
                }
            while (tmp.len>1&&!tmp.a[tmp.len])--tmp.len;
            return tmp;
        }*/
        pair<huge,huge> divide(const huge &a,const huge &b){
            int L=a.len;huge c,d;
            for (int i=L;i;--i){
                c.a[i]=0;d=d*base;d.a[1]=a.a[i];
                //while (d>=b){d-=b;++c.a[i];}
                int l=0,r=base-1,mid;
                while (l<r){
                    mid=(l+r+1)>>1;
                    if (b*mid<=d)l=mid;
                        else r=mid-1;
                }
                c.a[i]=l;d-=b*l;
            }
            while (L>1&&!c.a[L])--L;c.len=L;
            return make_pair(c,d);
        }
        huge operator /(value x){
            value d=0;huge tmp;
            for (int i=len;i;--i){
                d=d*base+a[i];
                tmp.a[i]=d/x;d%=x;
            }
            tmp.len=len;
            while (tmp.len>1&&!tmp.a[tmp.len])--tmp.len;
            return tmp;
        }
        value operator %(value x){
            value d=0;
            for (int i=len;i;--i)d=(d*base+a[i])%x;
            return d;
        }
        huge operator /(const huge &b){return divide(*this,b).first;}
        huge operator %(const huge &b){return divide(*this,b).second;}
        huge &operator +=(const huge &b){*this=*this+b;return *this;}
        huge &operator -=(const huge &b){*this=*this-b;return *this;}
        huge &operator *=(const huge &b){*this=*this*b;return *this;}
        huge operator /=(const huge &b){*this=*this/b;return *this;}
        huge operator %=(const huge &b){*this=*this%b;return *this;}
        huge &operator ++(){huge T;T=1;*this=*this+T;return *this;}
        huge &operator --(){huge T;T=1;*this=*this-T;return *this;}
        huge operator ++(int){huge T,tmp=*this;T=1;*this=*this+T;return tmp;}
        huge operator --(int){huge T,tmp=*this;T=1;*this=*this-T;return tmp;}
        huge operator +(value x){huge T;T=x;return *this+T;}
        huge operator -(value x){huge T;T=x;return *this-T;}
        huge operator *(value x){huge T;T=x;return *this*T;}
        //huge operator /(value x){huge T;T=x;return *this/T;}
        //huge operator %(value x){huge T;T=x;return *this%T;}
        huge operator *=(value x){*this=*this*x;return *this;}
        huge operator +=(value x){*this=*this+x;return *this;}
        huge operator -=(value x){*this=*this-x;return *this;}
        huge operator /=(value x){*this=*this/x;return *this;}
        huge operator %=(value x){*this=*this%x;return *this;}
        bool operator ==(value x){huge T;T=x;return *this==T;}
        bool operator !=(value x){huge T;T=x;return *this!=T;}
        bool operator <=(value x){huge T;T=x;return *this<=T;}
        bool operator >=(value x){huge T;T=x;return *this>=T;}
        bool operator <(value x){huge T;T=x;return *this<T;}
        bool operator >(value x){huge T;T=x;return *this>T;}
        huge operator =(value x){
            len=0;
            while (x)a[++len]=x%base,x/=base;
            if (!len)a[++len]=0;
            return *this;
        }
        bool operator <(const huge &b){
            if (len<b.len)return 1;
            if (len>b.len)return 0;
            for (int i=len;i;--i){
                if (a[i]<b.a[i])return 1;
                if (a[i]>b.a[i])return 0;
            }
            return 0;
        }
        bool operator ==(const huge &b){
            if (len!=b.len)return 0;
            for (int i=len;i;--i)
                if (a[i]!=b.a[i])return 0;
            return 1;
        }
        bool operator !=(const huge &b){return !(*this==b);}
        bool operator >(const huge &b){return !(*this<b||*this==b);}
        bool operator <=(const huge &b){return (*this<b)||(*this==b);}
        bool operator >=(const huge &b){return (*this>b)||(*this==b);}
        void str(char s[]){
            int l=strlen(s);value x=0,y=1;len=0;
            for (int i=l-1;i>=0;--i){
                x=x+(s[i]-'0')*y;y*=10;
                if (y==base)a[++len]=x,x=0,y=1;
            }
            if (!len||x)a[++len]=x;
        }
        void read(){
            scanf("%s",s);this->str(s);
        }
        void print(){
            printf("%d",(int)a[len]);
            for (int i=len-1;i;--i){
                for (int j=base/10;j>=10;j/=10){
                    if (a[i]<j)printf("0");
                        else break;
                }
                printf("%d",(int)a[i]);
            }
        }
    };char huge::s[N_huge*10];
    
    huge f[2][1025][2];
    int cur;
    
    int main(){
        read(n);
    	for(int i=1;i<=n;++i) read(a[i]);
        cur=0;
        f[cur][a[n]][0]=1;
        for(int i=n-1;i>=1;--i){
            cur^=1;
            for(int j=0;j<1024;++j) f[cur][j][0]=f[cur][j][1]=0;
            f[cur][a[i]][0]=1;
            for(int j=0;j<1024;++j){
                f[cur][j][0]+=f[cur^1][j][0];
                f[cur][j][1]+=f[cur^1][j][1];
                f[cur][j & a[i]][0]+=f[cur^1][j][0];
     			f[cur][j ^ a[i]][1]+=f[cur^1][j][0]+f[cur^1][j][1];
            }
        }
        f[cur][0][1].print();
        return 0;
    }
    

    T3 天神下凡

    不知道为神马取个这么高端的名字,就是(vijos)上的原题。。
    月光的魔法
    题面就不赘述了,我在(vijos)上也发了题解的,搬运过来算了。。

    思路:

    考虑一种新方法:括号匹配。
    对于每一个圆,记录其左右分别能到达的最远点(l) , (r)
    显然 (l) = (O)(圆心) - (R)(半径); (r = O + R)。分别为左括弧和右括弧
    然后得到一个(2n)的数组。
    对于任意一个圆,其贡献仅有可能为两种:(1)(2),其中(1)不必解释,当一个圆被其他圆沿半径方向分为两半,其贡献则为(2)
    则考虑括弧匹配,对于任意一个左括弧,记录其增加值(add)。有以下情况:

    1. 对于连续两个 (() ,他们的坐标相同,则前面一个的(add)暂时为(1)
    2. 对于 ()) 的出现,在栈中弹出第一个元素并把他的(add)(+1)记录到答案
    3. 对于连续的两个 ()) 的出现,且坐标相同,则栈顶的 (() (add)暂时为(1)
    4. 对于连续的 ())(() 出现,若坐标相同,则栈顶的 (() (add)暂时为(1)

    非以上情况所述,(add)均为(0)
    最后答案(+1),表示最外面的区域。复杂度(O(nlogn + 2n))

    #include<cstdio>
    #include<algorithm>
    #define inf 0x3f3f3f3f
    using namespace std;
    int n;
    const int MAXN = 300005;
    struct point{
        int l,r,val,add;
    }p[MAXN<<1];point s[MAXN<<1];point p1,p2;
    
    inline bool cmp(const point a,const point b){
        if(a.val == b.val) return a.r > b.r;
        else return a.val < b.val;
    }
    
    inline void read(int&x){
        x = 0;
        bool flag = false;
        char c = getchar();
        while (c<'0'||c>'9'){ 
            if (c == '-')
                flag = true; 
            c = getchar();
        } 
        while (c>='0'&&c<='9'){
            x = x*10+c-'0';
            c = getchar();
        }
        if (flag)
            x = -x;
    }
    
    int main(){
        read(n);int u = 0;
        for(int i=1;i<=n;++i){
            int o,r;read(o);read(r);
            p1.val = o + r;p2.val = o - r;
            p1.r = 1;p1.l = 0;p2.r = 0;p2.l = 1;
            p1.add = p2.add = 0;
            p[++u] = p1;
            p[++u] = p2;
        }
        sort(p+1,p+1+u,cmp);int tot=0;
        s[++tot] = p[1];int ans = 0;
        int last = inf;
        for(int i=2;i<=u;++i){
            if(p[i].l){
                if(p[i].val == s[tot].val) s[tot].add = 1;
                if(last != inf){
                    if(p[i].val != last) s[tot].add = 0;
                }
                last = inf;
                s[++tot] = p[i];
            }
            if(p[i].r){
                if(last == inf) last = p[i].val;
                else{
                    if(p[i].val !=  last) s[tot].add = 0;
                    last = p[i].val;
                }
                ans += (1 + s[tot].add);
                tot--;
            }
        }
        printf("%d",ans+1);
        return 0;
    }
    

    然而>_>
    机房(dalao)多,做法千万种,种种踩(std)

    比如:(蜜汁二分(rank1)

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    #define inl inline
    #define ll long long
    template<class X>inl void read(X &x)
    {
        X f=1;x=0;char c=getchar();
        for(;c>'9'||c<'0';c=getchar())if(c=='-')f=-1;
        for(;c<='9'&&c>='0';c=getchar())x=x*10+c-'0';
        x=x*f;
    }
    #define inf 1061109567
    #define N 300005
    #define rgs register 
    struct cer{int l,r;}c[N];
    inl bool cmp(const cer &a,const cer &b){return (a.l^b.l)?(a.l<b.l):(a.r>b.r);}
    int n;
    int r[N];//r:(最大的)右边缘外切圆; 
    int findr(int x)
    {
        int L=x+1,R=n,goal=c[x].r,ans=0;
        while(L<=R)
        {
            int mid(L+R>>1);
            if(c[mid].l==goal)ans=mid;
            if(c[mid].l>=goal)R=mid-1;
            else L=mid+1;
        }
        if(ans)while(c[ans-1].l==c[ans].l)--ans;
        r[x]=ans;
        return ans;
    }
    int main()
    {
        memset(r,-1,sizeof r);
        read(n);
        for(rgs int i=1;i<=n;++i)
        {
            int x,r;
            read(x),read(r);
            c[i].l=x-r,c[i].r=x+r;
        }sort(c+1,c+1+n,cmp);
        rgs int ans=1;
        for(rgs int i=1;i<=n;++i)
        {
            int x=i,Re=c[i].r;
            if(c[x+1].l^c[x].l){++ans;continue;}
            ++x;
            while(x)
            {
                x=(~r[x])?r[x]:findr(x);
                if(c[x].r==Re){++ans;break;}
            }++ans;
        }
        printf("%d",ans);
        return 0;
    }
    

    或者:线段树+离散化((4000ms+)

    #include<cstring>
    #include<algorithm>
    #include<cstdio>
    #include<cmath>
    #define LL long long
    #define file(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)
    #define gch getchar
    #define pch putchar
    #define ls (now<<1)
    #define rs (now<<1|1)
    using namespace std;
    template <class X> inline void read(X &x){
        x=0;char ch=gch();X f=1;
        while(ch>'9' || ch<'0') {if(ch=='-') f=-1;ch=gch();}
        while(ch>='0' && ch<='9') {x=(x<<1)+(x<<3)+ch-48;ch=gch();}
        x*=f;
    }
    template <class X> inline void print(X x){
        if(x<0) pch('-'),x=-x;
        if(x>9) print(x/10);
        pch(x%10+48);
    }
    
    const int MAXN=300000+5;
    
    int n,hash[MAXN<<1],hash_cnt,cnt;
    
    struct Segment{
        int l,r,len;
        bool operator < (const Segment &x)const{
            return len<x.len;
        }
    }s[MAXN];
    
    inline int pos(int x){
        return lower_bound(hash+1,hash+1+hash_cnt,x)-hash;
    }
    
    struct Segment_tree{
        int cou[MAXN<<3];
        inline void cover(int now,int l,int r,int L,int R){
            if(L<=l && r<=R){cou[now]++;return;}
            int mid=(l+r)>>1;
            if(L<=mid) cover(ls,l,mid,L,R);
            if(R>mid) cover(rs,mid+1,r,L,R);
            cou[now]=min(cou[ls],cou[rs]);
        }
        inline bool check(int now,int l,int r,int L,int R){
            if(L<=l && r<=R) return cou[now];
            int mid=(l+r)>>1;
            if(L<=mid && R>mid) return check(ls,l,mid,L,R)&&check(rs,mid+1,r,L,R);
            else if(L<=mid) return check(ls,l,mid,L,R);
            else if(R>mid) return check(rs,mid+1,r,L,R);
        }
    }T;
    
    int main(){
        read(n);
        for(int i=1;i<=n;++i){
            int x,y;read(x);read(y);
            s[i].l=x-y;s[i].r=x+y-1;
            s[i].len=y<<1;
            hash[++cnt]=s[i].l;
            hash[++cnt]=s[i].r;
        }
        sort(hash+1,hash+1+cnt);
        hash_cnt=unique(hash+1,hash+1+cnt)-(hash+1);
        for(int i=1;i<=n;++i){
            s[i].l=pos(s[i].l);
            s[i].r=pos(s[i].r);
        }
        sort(s+1,s+1+n);
        int ans=n+1;
        for(int i=1;i<=n;++i){
            if(T.check(1,1,hash_cnt,s[i].l,s[i].r)) ans++;
            T.cover(1,1,hash_cnt,s[i].l,s[i].r);
        }
        print(ans);
        return 0;
    }
    

    (or) 并查集大法好

    #include<map>
    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #define N 300005
    using namespace std;
    
    inline int read(){
        int e=0,ch=1;char c=getchar();
        while(c<'0'||c>'9'){if(c=='-')ch=-1;c=getchar();}
        while(c>='0'&&c<='9'){e=e*10+(c-48);c=getchar();}
        return e*ch;
    }
    
    int n,ans,m,c,d,cnt;
    int b[N<<1],fa[N<<1];
    
    struct node{
        int l,r;
    }e[N];
    
    struct ndqe{
        int rank,w,id,to;
    }pp[N<<1];
    
    inline int fin(int x){
        if(fa[x]!=x) return fa[x]=fin(fa[x]);
        return x;
    }
    
    inline bool cmp(ndqe x,ndqe y){
        return x.w<y.w;
    }
    
    inline bool cmp2(node x,node y){
        return (x.r-x.l)<(y.r-y.l);
    }
    
    int main(){
        n=read();
        ans=n+1;
        for(int i=1;i<=n;++i){
            c=read();
            d=read();
            e[i].l=c-d;
            e[i].r=c+d;
            pp[++cnt].id=i;
            pp[cnt].w=c-d;
            pp[cnt].to=1;
            pp[++cnt].id=i;
            pp[cnt].w=c+d;
            pp[cnt].to=0;
        }
        sort(pp+1,pp+cnt+1,cmp);
        pp[1].rank=1;
        for(int i=2;i<=cnt;++i){
            if(pp[i].w>pp[i-1].w) pp[i].rank=pp[i-1].rank+1;
            else pp[i].rank=pp[i-1].rank;
        }
        for(int i=1;i<=cnt;++i){
            if(pp[i].to) e[pp[i].id].l=pp[i].rank;
            else e[pp[i].id].r=pp[i].rank;
        }
        for(int i=1;i<=pp[cnt].rank;++i) fa[i]=i;
        sort(e+1,e+n+1,cmp2);
        for(int i=1;i<=n;++i){
            int l=e[i].l,r=e[i].r;
            l=fin(l),r=fin(r);
            if(l==r) ans++;
            else fa[l]=r;
        }
        printf("%d",ans);
        return 0;
    }
    

    还有一个奇怪的栈模拟

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<stack>
    using namespace std;
    struct Info {
        int left,r,o,right,ind;
        
        Info(int o,int r) {
            this->left = o - r;
            this->right = o + r;
            this->r = r;
            this->o = o;
        }
        Info(Info info,int ind) {
            this->ind = ind;
            this->left = info.left;
            this->right = info.right;
            this->r = info.r;
            this->o = info.o;
        }
        Info(){
        }
        
        bool operator<(Info info) const {
            if (left == info.left)
                return r>info.r;
            else return left<info.left;
        }
    };
    
    Info infos[300005];
    
    stack<Info> sta;
    
    int sizes[300005];
    
    void read(int&x){cin>>x;}
    
    int main() {
        int n;
        read(n);
        for (int i = 0;i<n;i++) {
            int o,r;
            read(o);
            read(r);
            infos[i] = Info(o,r);
        }
        sort(infos,infos+n);
        int ans = 2;
        sta.push(Info(infos[0],0));
        for (int i = 1;i<n;i++) {
            ans++;
            Info info = infos[i];
            Info top = sta.top();
            while (info.left>=top.right&&!sta.empty()) {
                sta.pop();
                if (!sta.empty())
                    top = sta.top();
            }
            if (!sta.empty())  
                sizes[top.ind] += info.r*2;
            sta.push(Info(info,i));
        }
        for (int i = 0;i<n;i++) 
            if (sizes[i]==infos[i].r*2) 
                 ans++;
        cout<<ans<<endl;
    } 
    

  • 相关阅读:
    网络最大流算法—最高标号预流推进HLPP
    网络最大流算法—EK算法
    PROPAGATION_REQUIRED
    js左侧三级菜单导航代码
    Ubuntu上用premake编译GDAL
    2013数据结构课程设计之便利店选址(暴力枚举和随机函数两种做法)
    JAVA环境配置
    [K/3Cloud] 如何从被调用的动态表单界面返回数据
    document.getElementsByClassName在ie8及其以下浏览器的兼容性问题
    Java学习笔记51:数组转ArrayList和ArrayList转数组技巧
  • 原文地址:https://www.cnblogs.com/lajioj/p/9466233.html
Copyright © 2011-2022 走看看