2017 Multi-University Training Contest - Team 2

2017 Multi-University Training Contest - Team 2

01    签到

#include<bits/stdc++.h>
using namespace std;
#pragma comment(linker, "/STACK:102400000,102400000")
#define rep(i,a,b) for (int i=a; i<=b; ++i)
#define per(i,b,a) for (int i=b; i>=a; --i)
#define mes(a,b)  memset(a,b,sizeof(a))
#define INF 0x3f3f3f3f
#define MP make_pair
#define PB push_back
#define fi  first
#define se  second
typedef long long ll;
const int N = 300005;

int n, x, y;
char A[N], B[N];
int main()
{
    int T;  scanf("%d", &T);
    while(T--)
    {
        int cnt1=0, cnt2=0;
        scanf("%d %d %d", &n, &x, &y);
        scanf("%s %s", A, B);
        rep(i,0,n-1)
            if(A[i]==B[i]) ++cnt1;
            else  ++cnt2;
        int mi = x>cnt2 ? x-cnt2 : 0;
        int mx = min(x, cnt1) + cnt2 - (x>cnt1 ? x-cnt1 : 0);
        puts((mi<=y && y<=mx) ? "Not lying" : "Lying");
    }

    return 0;
}
View Code

03    单调队列或线段树

#include<bits/stdc++.h>
using namespace std;
#pragma comment(linker, "/STACK:102400000,102400000")
#define rep(i,a,b) for (int i=a; i<=b; ++i)
#define per(i,b,a) for (int i=b; i>=a; --i)
#define mes(a,b)  memset(a,b,sizeof(a))
#define INF 0x3f3f3f3f
#define MP make_pair
#define PB push_back
#define fi  first
#define se  second
#define  PII  pair<ll, int >
typedef long long ll;
const int N = 250005, mod = 1e9+7;

int n;
ll a[N], b[N];
deque<PII > q;
int main()
{
    while(scanf("%d", &n)!=EOF)
    {
        q.clear();
        rep(i,1,n) scanf("%lld", &a[i]);
        rep(i,1,n) scanf("%lld", &b[i]);
        sort(b+1, b+1+n);
        q.push_front(MP(a[1]-1, 1));
        PII  u;
        rep(i,2,n)
        {
            u=q.front();
            while(!q.empty() && u.fi <= a[i]-i) {
                q.pop_front();
                u=q.front();
            }
            q.push_front(MP(a[i]-i, i));
        }
        ll  ans=0, ai;
        rep(i,1,n)
        {
            u=q.back();
            while(u.se < b[i]) {
                q.pop_back();
                u=q.back();
            }
            ai = u.fi;
            ( ans += ai ) %= mod;
            u=q.front();
            while(!q.empty() && u.fi <= ai-n-i) {
                q.pop_front();
                u=q.front();
            }
            q.push_front(MP(ai-n-i, n+i));
        }
        printf("%lld\n", (ans+mod)%mod);
    }

    return 0;
}
View Code

09    莫比乌斯函数,思维

题意: 给出数组 a[],求满足下面条件的数组 b[]。

* 1≤Bi≤Ai
* For each pair( l , r ) (1≤l≤r≤n) , gcd(bl,bl+1...br)≥2

tags: 想到枚举 [2,min(a[]) ) 作为 gcd,对于每个gcd,答案就是 a[1]/gcd+a[2]/gcd+....+a[n]/gcd,但显然超时。 这里换个思维,对于每个gcd,它的一个倍数 g1,g1对应的 a[] 里面的范围是 ( g1-1,  min(mx, g1+gcd) ] ,我们可以预处理出 a[] 在这个范围的个数。  然后发现会有重复,可以按莫比乌斯函数在计算中去重,也可以计算好后筛一遍。 

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#include<string>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<bitset>
#include<vector>
#include<set>
#include<list>
using namespace std;
#pragma comment(linker, "/STACK:102400000,102400000")
#define rep(i,a,b) for (int i=a; i<=b; ++i)
#define per(i,b,a) for (int i=b; i>=a; --i)
#define mes(a,b)  memset(a,b,sizeof(a))
#define INF 0x3f3f3f3f
#define MP make_pair
#define PB push_back
#define fi  first
#define se  second
typedef long long ll;
const int N = 100005, mod = 1e9+7;

int mu[N];
void mobius(int mn)
{
    mu[1] = 1;
    for(int i=1; i<=mn; ++i)
        for(int j=i+i; j<=mn; j+=i)
            mu[j] -= mu[i];
}
int n, a[N], num[N];
ll  fpow(ll a,int b) {ll ans=1; for(;b;a=a*a%mod, b>>=1)if(b&1)ans=ans*a%mod; return ans; }
int main()
{
    mobius(100000);
    int T, cas=0;  scanf("%d", &T);
    while(T--)
    {
        mes(num, 0);
        int mi=INF, mx=0;
        scanf("%d", &n);
        rep(i,1,n)
        {
            scanf("%d", &a[i]);
            ++num[a[i]];
            mi = min(mi, a[i]);
            mx = max(mx, a[i]);
        }
        rep(i,1,N-1) num[i] += num[i-1];
        ll  ans=0;
        rep(i,2,mi) if(mu[i])
        {
            ll ans1=1;
            for(ll j=i; j<=mx; j+=i)
            {
                int cnt = num[min(mx, (int)j+i-1)] - num[j-1];
                ( ans1 *= fpow(j/i, cnt) ) %= mod;
            }
            ( ans += ans1*(-1)*mu[i] ) %= mod;
        }
        printf("Case #%d: %lld\n", ++cas, (ans+mod)%mod);
    }

    return 0;
}
View Code

11    整数点只能形成正四边形。然后暴力枚举

#include<bits/stdc++.h>
using namespace std;
#pragma comment(linker, "/STACK:102400000,102400000")
#define rep(i,a,b) for (int i=a; i<=b; ++i)
#define per(i,b,a) for (int i=b; i>=a; --i)
#define mes(a,b)  memset(a,b,sizeof(a))
#define INF 0x3f3f3f3f
#define MP make_pair
#define PB push_back
#define fi  first
#define se  second
#define  PII  pair<int, int >
typedef long long ll;
const int N = 200005;

int n;
PII  p[505];
map<PII ,int  > mp;
int main()
{
    while(~scanf("%d", &n))
    {
        mp.clear();
        rep(i,1,n)
        {
            scanf("%d %d", &p[i].fi, &p[i].se);
            ++mp[p[i]];
        }
        ll  ans=0;
        rep(i,1,n) rep(j,1,i-1)
        {
            PII  a1=p[i], a2=p[j];
            if(a1.se > a2.se) swap(a1, a2);
            if(a1.fi>a2.fi || a1.se==a2.se) continue;
            int a=abs(a2.fi-a1.fi), b=abs(a2.se-a1.se);
            PII  a3, a4;
            a3=MP(a1.fi+b, a1.se-a), a4=MP(a2.fi+b,a2.se-a);
            if(mp.find(a3)!=mp.end() && mp.find(a4)!=mp.end()) {
                ++ans;
            }
        }
        printf("%lld\n", ans);
    }

    return 0;
}
View Code
posted @ 2017-07-29 09:43  v9fly  阅读(174)  评论(0编辑  收藏  举报