zoukankan      html  css  js  c++  java
  • 2018 Multi-University Training Contest 5

    Beautiful Now

    题意:

      定义一次合法的交换(i,j)为交换n的第i位与第j位数且不能出现前导0(i和j可以相同),问n经过k次交换后的最小值和最大值分别是多少。

    分析:

      贪心是原罪啊,后来写了个bfs过了,注意下剪枝就好了。对于求最大值,如果arr【i】< arr【j】且arr【j】为n的第i+1位到末尾上的最大值,才进行交换;如果已经达到所能循环的最大值直接跳出循环。对于求最小值也是同理,不过对于前导0的情况特判掉就好了。比赛代码写的臭长臭长的,就不贴了。

    Everything Has Changed

    题意:

      给出一个圆盘,给出n个小圆的圆心和半径,每次从圆盘中切去小圆(大圆小圆不一定有交集),保证小圆没有交集且没有一个小圆包含整个圆,问最后圆盘的周长是多少?

    分析:

      余弦定理求出角度,然后算出弧长就好了。

    代码:

    #include <map>
    #include <queue>
    #include <math.h>
    #include <string>
    #include <stdio.h>
    #include <string.h>
    #include <iostream>
    #include <algorithm>
    
    using namespace std;
    #define ll long long
    #define ui unsigned int
    #define ull unsigned long long
    #define cls(x) memset(x,0,sizeof(x))
    #define clslow(x) memset(x,-1,sizeof(x))
    
    const int maxn=1e5+100;
    const double PI=acos(-1.0);
    
    int n,R,x,y,r,T;
    
    double normal(double x)
    {
        return min(max(-1.0,x),1.0);
    }
    
    double getangle(int a,int b,int c)
    {
        double cosa=(a+b-c)*1.0/(2*sqrt(a)*sqrt(b));
        return acos(normal(cosa));
    }
    
    int main()
    {
    //    freopen("in.txt","r",stdin);
        scanf("%d",&T);
        while(T--)
        {
            scanf("%d%d",&n,&R);
            double p=2.0*PI*R;
            for(int i=1;i<=n;i++){
                scanf("%d%d%d",&x,&y,&r);
                //外切和外离
                if(x*x+y*y>=(R+r)*(R+r))    continue;
                //包含
                if(x*x+y*y<(R-r)*(R-r)) continue;
                //内切
                if(x*x+y*y==(R-r)*(R-r)){
                    p+=2*PI*r;
                    continue;
                }
                //相交
                double arc1=2.0*getangle(R*R,x*x+y*y,r*r)*R;
                double arc2=2.0*getangle(r*r,x*x+y*y,R*R)*r;
                p-=arc1;p+=arc2;
            }
            printf("%lf
    ",p);
        }
        return 0;
    }
    View Code

    Glad You Came

    题意:

      给出m次操作,每次操作包含3个数l,r,v,对于a数组如果a【l】……a【r】存在有值小于v,则把该值更新为v,求(1*a【1】)^(2*a【2】)……^(n*a【n】)的值。

    分析:

      暴力更新肯定是不行的,考虑使用线段树或者st表来维护区间的最小值,如果某段区间的最小值小于v,则更新区间。

    代码:

    线段树

    #include <map>
    #include <queue>
    #include <math.h>
    #include <string>
    #include <stdio.h>
    #include <string.h>
    #include <iostream>
    #include <algorithm>
    
    using namespace std;
    #define ll long long
    #define ui unsigned int
    #define ull unsigned long long
    #define cls(x) memset(x,0,sizeof(x))
    #define clslow(x) memset(x,-1,sizeof(x))
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    
    const int maxn=1e5+100;
    const int maxm=5e6+100;
    
    ll ans;
    int n,m,T;
    ui x,y,z;
    
    ui f[maxm*3];
    ll minval[maxn<<2];
    
    ui getf(ui& x,ui& y,ui& z)
    {
        x^=(x<<11);
        x^=(x>>4);
        x^=(x<<5);
        x^=(x>>14);
        ui w=x^(y^z);
        x=y;
        y=z;
        z=w;
        return z;
    }
    
    void PushUp(int rt)
    {
        minval[rt]=min(minval[rt<<1],minval[rt<<1|1]);
    }
    
    void PushDown(int rt)
    {
        if(minval[rt]){
            minval[rt<<1]=max(minval[rt],minval[rt<<1]);
            minval[rt<<1|1]=max(minval[rt],minval[rt<<1|1]);
            minval[rt]=0;
        }
    }
    
    void build(int l,int r,int rt)
    {
        if(l==r){
            minval[rt]=0;
            return;
        }
        int m=(l+r)>>1;
        build(lson);
        build(rson);
        PushUp(rt);
    }
    
    void update(int L,int R,int val,int l,int r,int rt)
    {
        if(minval[rt]>=val) return;
        if(L<=l&&r<=R){
            minval[rt]=val;
            return;
        }
        PushDown(rt);
        int m=(l+r)>>1;
        if(L<=m)    update(L,R,val,lson);
        if(R>m)     update(L,R,val,rson);
        PushUp(rt);
    }
    
    void query(int l,int r,int rt)
    {
        if(l==r){
            ans=ans^((ll)l*minval[rt]);
            return;
        }
        PushDown(rt);
        int m=(l+r)>>1;
        query(lson);
        query(rson);
    }
    
    void debug(int l,int r,int rt)
    {
        if(l==r){
            cout<<l<<" "<<minval[rt]<<endl;
            return;
        }
        PushDown(rt);
        int m=(l+r)>>1;
        debug(lson);
        debug(rson);
    }
    
    int main()
    {
    //    freopen("in.txt","r",stdin);
        scanf("%d",&T);
        while(T--)
        {
            scanf("%d %d %u %u %u",&n,&m,&x,&y,&z);
            for(int i=1;i<=m*3;i++){
                f[i]=getf(x,y,z);
            }
    
            build(1,n,1);
            for(int i=1;i<=m;i++){
                int l,r,v;
                l=min(f[3*i-2]%n+1,f[3*i-1]%n+1);
                r=max(f[3*i-2]%n+1,f[3*i-1]%n+1);
                v=f[3*i]%(1<<30);
                update(l,r,v,1,n,1);
            }
            ans=0;
    //        debug(1,n,1);
            query(1,n,1);
            printf("%lld
    ",ans);
        }
        return 0;
    }
    View Code

    ST表

    #include <map>
    #include <queue>
    #include <math.h>
    #include <string>
    #include <stdio.h>
    #include <string.h>
    #include <iostream>
    #include <algorithm>
    
    using namespace std;
    #define ll long long
    #define ui unsigned int
    #define ull unsigned long long
    #define cls(x) memset(x,0,sizeof(x))
    #define clslow(x) memset(x,-1,sizeof(x))
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    
    const int maxn=1e5+100;
    const int maxm=5e6+100;
    
    ll ans;
    int n,m,T;
    ui x,y,z;
    
    ui f[maxm*3];
    int lg2[maxn];
    
    ui getf(ui& x,ui& y,ui& z)
    {
        x^=(x<<11);
        x^=(x>>4);
        x^=(x<<5);
        x^=(x>>14);
        ui w=x^(y^z);
        x=y;
        y=z;
        z=w;
        return z;
    }
    
    void getlg2()
    {
        lg2[1]=0;
        for(int i=2;i<maxn;i++){
            lg2[i]=lg2[i/2]+1;
        }
    }
    
    struct ST {
        int d[maxn][20];
        void init(int n)
        {
            int len=lg2[n];
            for(int i=0;i<=len;i++){
                for(int j=1;j<=n;j++){
                    d[j][i]=0;
                }
            }
        }
        void update(int l,int r,int val)
        {
            int len=lg2[r-l+1];
            d[l][len]=max(val,d[l][len]);
            d[r-(1<<len)+1][len]=max(val,d[r-(1<<len)+1][len]);
        }
        ll query(int l,int r)
        {
            int len=lg2[r-l+1];
            for(int i=len;i>=1;i--){
                for(int j=l;j<=r;j++){
                    if(j+(1<<i)-1>r)  break;
                    d[j][i-1]=max(d[j][i],d[j][i-1]);
                    d[j+(1<<(i-1))][i-1]=max(d[j][i],d[j+(1<<(i-1))][i-1]);
                }
            }
            ll res=0;
            for(int i=l;i<=r;i++){
                res=res^((ll)d[i][0]*i);
            }
            return res;
        }
    };
    ST st;
    
    int main()
    {
    //    freopen("in.txt","r",stdin);
        getlg2();
        scanf("%d",&T);
        while(T--)
        {
            scanf("%d %d %u %u %u",&n,&m,&x,&y,&z);
            for(int i=1;i<=m*3;i++){
                f[i]=getf(x,y,z);
            }
    
            st.init(n);
            for(int i=1;i<=m;i++){
                int l,r,v;
                l=min(f[3*i-2]%n+1,f[3*i-1]%n+1);
                r=max(f[3*i-2]%n+1,f[3*i-1]%n+1);
                v=f[3*i]%(1<<30);
                st.update(l,r,v);
            }
            printf("%lld
    ",st.query(1,n));
        }
        return 0;
    }
    View Code
  • 相关阅读:
    设计模式总结:单例模式(以及多线程、无序写入、volatile对单例的影响)
    android的WebView进度条
    三角形类内置成员函数(看看吧。。)
    VGA接口之显示彩色条
    Java I/O流操作(二)缓冲流
    oracle 单引号 双引号 连接符
    2013腾讯编程马拉松初赛(3月22)赛题及第2题代码(C++)
    Java I/O流操作(一)入门篇和System和Properties类介绍
    POJ 3264 Balanced Lineup
    成都行(二)
  • 原文地址:https://www.cnblogs.com/shutdown113/p/9437825.html
Copyright © 2011-2022 走看看