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; }
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; }
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; }
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; }