2017 Multi-University Training Contest - Team 6

时间:2023-01-12 04:29:35

206/734

1002.Mindis【补】

图上一点关于圆心的反演

2017 Multi-University Training Contest - Team 62017 Multi-University Training Contest - Team 6
#include <bits/stdc++.h>
using namespace std;
const int maxn=500005;
const long double eps=1e-15;
int sgn ( long double x ) {
    return ( x > eps ) - ( x < -eps ) ;
}
struct Point{
    long double x,y;
    Point(){}
    Point(long double _x,long double _y){
        x=_x;y=_y;
    }
    Point operator +(const Point &b)const{
        return Point(x+b.x,y+b.y);
    }
    Point operator /(const long double &k)const{
        return Point(x/k,y/k);
    }
    Point operator -(const Point &b)const {
        return Point(x-b.x,y-b.y);
    }
    Point operator *(const long double &rhs)const{
        return Point(x*rhs,y*rhs);
    }
    long double operator*(const Point &b)const{
        return x*b.x+y*b.y;
    }
    long double operator ^(const Point &b) const {
        return x*b.y-y*b.x;
    }
    bool operator==(Point b)const{
        return sgn(x-b.x)==0&&sgn(y-b.y)==0;
    }
    long double len() {
        return sqrt(x*x+y*y);
    }
    long double len2() {
        return x*x+y*y;
    }
    long double distance(Point p) {
        return sqrt((x-p.x)*(x-p.x)+(y-p.y)*(y-p.y));
    }
    Point rotleft(){
        return Point(-y,x);
    }
    Point trunc(long double r) {
        long double l=len();
        if (!sgn(l))
            return *this;
        r/=l;
        return Point(x*r,y*r);
    }
};
struct Line{
    Point s,e;
    Line(){}
    Line(Point _s,Point _e){
        s=_s;
        e=_e;
    }
    long double length() {
        return s.distance(e);
    }
    long double dispointtoline(Point p) {
        return fabs((p-s)^(e-s))/length();
    }
    Point crosspoint(Line v) {
        long double a1=(v.e-v.s)^(s-v.s);
        long double a2=(v.e-v.s)^(e-v.s);
        return Point((s.x*a2-e.x*a1)/(a2-a1),(s.y*a2-e.y*a1)/(a2-a1));
    }
    Point lineprog(Point p) {
        return s+(((e-s)*((e-s)*(p-s)))/((e-s).len2()));
    }
};
struct Circle{
    Point p;long double r;
    Circle(){}
    Circle(long double x,long double y,long double _r) {
        p=Point(x,y);
        r=_r;
    }
    int relationline(Line v) {
        long double dst=v.dispointtoline(p);
        if (sgn(dst-r)<0)
            return 2;
        else if (sgn(dst-r)==0)
            return 1;
        else return 0;
    }
    int pointcrossline(Line v,Point &p1,Point &p2) {
        if (!(*this).relationline(v))
            return 0;
        Point a=v.lineprog(p);
        long double d=v.dispointtoline(p);
        d=sqrt(r*r-d*d);
        if (sgn(d)==0) {
            p1=a;
            p2=a;
            return 1;
        }
        p1=a+(v.e-v.s).trunc(d);
        p2=a-(v.e-v.s).trunc(d);
        return 2;
    }
};
long double dist(Point p,Point q) {
    return p.distance(q);
}
int main()
{
    int T;
    Point c=Point(0,0);
    scanf("%d",&T);
    while (T--) {
        double t;
        long double r;
        long double x1,y1,x2,y2;
        //cin >> r;
        //cin >>x1 >>y1;
        //cin >>x2 >>y2;
        scanf("%lf",&t);r =t;
        scanf("%lf",&t);x1 =t;
        scanf("%lf",&t);y1 =t;
        scanf("%lf",&t);x2 = t;
        scanf("%lf",&t);y2 = t;

        Point P(x1,y1);
        Point Q(x2,y2);
        long double rr = P.distance(c);
        long double k = r*r/(rr*rr);
        Point PP(x1*k,y1*k);
        Point QQ(x2*k,y2*k);
        Line L(PP,QQ);
        Circle C(0,0,r);
        Point a;
        long double ans = 0;
        if (P==Q)
        {
            ans = 2*(r-rr);
        }
        else if (C.relationline(L) >=1 )
        {
            ans = PP.distance(QQ)*rr/r;
        }
        else
        {
            Point mid = ((P+Q)/2);
            Line Y(mid,c);
            Point p1,p2;
            C.pointcrossline(Y,p1,p2);
            ans = min(p1.distance(P)+p1.distance(Q),p2.distance(P)+p2.distance(Q));
        }
        double res = (double)ans;

        printf("%.12f\n",res);
    }
    return 0;
}
View Code

1003. Inversion

暴力。先打个ST表,对每个Bi暴力求最大值即可。

2017 Multi-University Training Contest - Team 62017 Multi-University Training Contest - Team 6
#include <bits/stdc++.h>
using namespace std;
const int maxn=100005;
int T,n,a[maxn],dp[19][maxn];
inline void init() {
    for (int i=1;i<=n;++i)
        dp[0][i]=a[i];
    for (int i=1;i<19;++i)
        for (int j=1;j+(1<<i)-1<=n;++j)
            dp[i][j]=max(dp[i-1][j],dp[i-1][j+(1<<(i-1))]);
}
inline int query(int l,int r) {
    int x=0;
    while ((1<<(x+1))<=r-l+1)
        ++x;
    return max(dp[x][l],dp[x][r-(1<<x)+1]);
}
int main()
{
    scanf("%d",&T);
    while (T--) {
        scanf("%d",&n);
        for (int i=1;i<=n;++i)
            scanf("%d",&a[i]);
        init();
        for (int i=2;i<=n;++i) {
            int res=0;
            for (int j=1;j<=n;j+=i)
                res=max(res,query(j,min(n,j+i-2)));
            printf("%d%c",res,i==n?'\n':' ');
        }
    }
    return 0;
}
View Code

1008. Kirinriki

暴力。枚举中点+双指针。复杂度O(n^2)

2017 Multi-University Training Contest - Team 62017 Multi-University Training Contest - Team 6
#include <bits/stdc++.h>
const long long mod = 1e9+7;
const double ex = 1e-10;
#define inf 0x3f3f3f3f
using namespace std;
char S[5500];
int l ;
int m;
int check1(int mid)
{
    int L = max(0,2*mid-l+1);
    int R = min(l-1,2*mid);
    int ll = L;
    int rr = R;
    int tans = 0;
    int sum = 0;
    //cout << mid <<":"<<endl;
    while (L<mid){
        sum += abs(S[L]-S[R]);
        while (sum > m) sum -= abs(S[ll++]-S[rr--]);
        tans = max(tans,L-ll+1);
        //cout << ll <<" " << L <<" "<<rr <<" " <<R <<" "<<sum <<endl;
        L++,R--;

    }
    return tans;
}
int check2(int mid)
{
    int L = max(0,2*mid-l+2);
    int R = min(l-1,2*mid+1);
    int ll = L;
    int rr = R;
    int tans = 0;
    int sum = 0;
    //cout << mid <<":"<<endl;
    while (L<=mid){
        sum += abs(S[L]-S[R]);
        while (sum > m) sum -= abs(S[ll++]-S[rr--]);
        tans = max(tans,L-ll+1);
        //cout << ll <<" " << L <<" "<<rr <<" " <<R <<" "<<sum <<endl;
        L++,R--;
    }
    return tans;
}
int main()
{
    int t;
    scanf("%d",&t);
    while (t--){

        scanf("%d",&m);
        scanf("%s",S);
        l = strlen(S);
        int ans = 0;
        for (int i = 0; i < l; i++){
            ans = max(ans,check1(i));
            if (i+1 == l) continue;
            ans = max(ans,check2(i));
        }
        printf("%d\n",ans);
    }
    return 0;
}
View Code

1010. Gameia

2017 Multi-University Training Contest - Team 62017 Multi-University Training Contest - Team 6
#include <bits/stdc++.h>
using namespace std;
const int maxn=505;
int T,n,K,fa[maxn],deg[maxn],vis[maxn];
inline void solve() {
    int tot=0;
    for (int i=1;i<=n;++i)
        if (!deg[i]) {
            int u=i;
            while (true) {
                if (u==1||vis[fa[u]]) {
                    puts("Alice");
                    return;
                }
                vis[u]=vis[fa[u]]=1;
                if (fa[u]==1)
                    break;
                ++tot;
                if (vis[fa[fa[u]]])
                    break;
                --deg[fa[fa[u]]];
                --deg[fa[u]];
                if (deg[fa[fa[u]]]>0)
                    break;
                u=fa[fa[u]];
            }
        }
    puts(tot<=K?"Bob":"Alice");
}
int main()
{
    scanf("%d",&T);
    while (T--) {
        memset(vis,0,sizeof vis);
        memset(deg,0,sizeof deg);
        scanf("%d%d",&n,&K);
        for (int i=2;i<=n;++i) {
            scanf("%d",&fa[i]);
            ++deg[fa[i]];
        }
        solve();
    }
    return 0;
}
View Code

1011. Classes

画出venn图,所有块大小都大于等于0就合法。

2017 Multi-University Training Contest - Team 62017 Multi-University Training Contest - Team 6
#include <bits/stdc++.h>
#define maxn 100010
#define inf 0x3f3f3f3f
#define REP(i,x,y) for(int i=x;i<(y);i++)
#define RREP(i,x,y) for(int i=x;i>(y);i--)
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
int a,b,c,ab,bc,ac,abc;
int main()
{
    int T;scanf("%d",&T);
    while(T--) {
        int n;scanf("%d",&n);
        int maxx=0;
        while(n--) {
            scanf("%d %d %d %d %d %d %d",&a,&b,&c,&ab,&bc,&ac,&abc);
            int sum=a+b+c-ab-bc-ac+abc;
            if(sum<0) continue;
            int tmp1=a-ab-ac+abc;
            if(tmp1<0) continue;
            tmp1=ab-abc;
            if(tmp1<0) continue;
            if(abc<0) continue;
            if(ac-abc<0) continue;
            if(bc-abc<0) continue;
            if(b-bc-ab+abc<0) continue;
            if(c-bc-ac+abc<0) continue;
            maxx=max(maxx,sum);
        }
        printf("%d\n",maxx);
    }
}
View Code