GYM-ACM International Collegiate Programming Contest, JUST Collegiate Programming Contest (2018)
阿新 • • 發佈:2018-11-01
GYM 兩星級難度還是比較簡單,隨便寫個題解吧。
http://codeforces.com/gym/101853
沒啥好講的的,離散化一下就隨便寫。
#include<bits/stdc++.h> #define lson rt<<1 #define rson rt<<1|1 #define fi first #define se second #define lowbit(x) (x&(-(x))) #define mme(a,b) memset((a),(b),sizeof((a))) #define fuck(x) cout<<"* "<<x<<"\n" #define iis std::ios::sync_with_stdio(false) using namespace std; typedef long long LL; const int N = 1e6 + 7; const int ME = 1e5 + 7; const int mod = 998244353; const int INF = 0x3f3f3f3f; const LL INFLL = 0x3f3f3f3f3f3f3f3f; typedef pair<int,int> pii; int n, m, q; struct lp{ int opt,x,y; }op[ME]; int vis[N],ar[N],br[N],now[N]; int main(){ int tim; scanf("%d",&tim); while(tim--){ scanf("%d%d", &n, &q); mme(vis,0);int tot=0; for(int i=1;i<=n;++i){ scanf("%d",&ar[i]); br[tot++]=ar[i]; } br[tot++]=0; for(int i=0;i<q;++i){ int opt,x,y; scanf("%d",&opt); op[i].opt=opt; if(opt==1){ scanf("%d%d",&x,&y); op[i].x=x;op[i].y=y; br[tot++]=y; } } sort(br,br+tot); int k = unique(br,br+tot)-br,sum=0; for(int i=1;i<=n;++i){ now[i]=lower_bound(br,br+k,ar[i])-br+1; if(now[i]==1)continue; vis[now[i]]++; if(vis[now[i]]==1)sum++; } for(int i=0;i<q;++i){ if(op[i].opt==2){ printf("%d\n", sum); }else{ int x=op[i].x,y=op[i].y; if(now[x]!=1){ vis[now[x]]--; if(vis[now[x]]==0)sum--; } now[x]=lower_bound(br,br+k,y)-br+1; if(now[x]!=1){ vis[now[x]]++; if(vis[now[x]]==1)sum++; } } } } return 0; }
B - New Assignment
看一眼就知道是最大匹配,難的是建圖。
有公共因子的男女可以配對,暴力 n^2logn,絕對超時。所以首先篩選所有的質因子,然後求每個數的所有的質因子,如果某個素數同時是兩個數的質因子切這兩個人性別不同就建邊。然後求最大匹配,用n-最大匹配就是答案。
我的寫法有點亂,看不懂留言。。。。
#include<iostream> #include<algorithm> #include<cstring> #include<string> #include<vector> #include<cstdio> #include<cstdlib> #include<cmath> #include<queue> #include<map> #include<set> #include<stack> using namespace std; typedef long long ll; typedef unsigned long long ull; typedef pair<int,int> P; #define bug printf("*********\n"); #define debug(x) cout<<"["<<x<<"]" <<endl; #define mid (l+r)/2 #define chl 2*k+1 #define chr 2*k+2 #define lson l,mid,chl #define rson mid,r,chr #define pb push_back #define mem(a,b) memset(a,b,sizeof(a)); const long long mod=998244353; const int maxn=1e6+5; const int INF=0x7fffffff; const int inf=0x3f3f3f3f; const double eps=1e-8; const double pi=acos(-1); struct edge { int to,cap,rev; }; vector <edge> G[maxn]; int level[maxn]; int iter[maxn]; void init(int _n) { for(int i=0; i<=_n; i++) { G[i].clear(); } } void bfs(int s) { memset(level,-1,sizeof(level)); queue<int> que; level[s]=0; que.push(s); while(!que.empty()) { int v= que.front(); que.pop(); for(int i=0; i<G[v].size(); i++) { edge & e=G[v][i]; if(e.cap>0&&level[e.to]<0) { level[e.to]=level[v] + 1; que.push(e.to); } } } } void add(int from,int to,int cap) { edge eg; eg.to=to; eg.cap=cap; eg.rev=G[to].size(); G[from].push_back(eg); eg.to=from; eg.cap=0; eg.rev=G[from].size()-1; G[to].push_back(eg); } int dfs(int v,int t,int f) { if(v == t)return f; for(int &i = iter[v]; i < G[v].size(); i++) { edge &e=G[v][i]; if(e.cap>0 && level[v]<level[e.to]) { int d=dfs(e.to,t,min(f,e.cap)); if(d>0) { e.cap-=d; G[e.to][e.rev].cap+=d; return d; } } } return 0; } int maxflow(int s,int t) { int flow=0; for(;;) { bfs(s); if(level[t]<0)return flow; memset(iter,0,sizeof(iter)); int f; while((f = dfs(s,t,INF))>0) { flow +=f; } } } int a[maxn],b[maxn]; int prime[maxn]; vector<int> v; void sieve(int _n) { int tot=0; memset(prime,0,sizeof(prime)); prime[0]=1; prime[1]=1; for(int i=2; i<=_n; i++) { if (prime[i]==0) { prime[i]=tot++; //是第幾個素數 v.push_back(i); for(int j=i*2; j<=_n; j+=i) { prime[j]=1; } } } } vector<int> k[maxn/10]; void df(int x,int pos) { //女的有某個質因子就把她加入質因子這個集合 if(x==1)return; for(int i=0; i<v.size(); i++) { if(x<v[i]) { return ; } if(prime[x]!=1&&prime[x]!=x) {//優化,如果當前這個數是已經是質數就直接加進去 k[prime[x]].push_back(pos); return ; } if(x%v[i]==0)k[i].push_back(pos); while(x%v[i]==0) { x/=v[i]; } } } void df2(int x,int pos) { //男的如果有某個因子且這個質因子也是某個女的的質因子,就建邊 if(x==1)return; for(int i=0; i<v.size(); i++) { if(x<v[i]) { return ; } if(prime[x]!=1&&prime[x]!=x) { i=prime[x]; for(int j=0; j<k[i].size(); j++) { add(k[i][j],pos,1); } return ; } if(x%v[i]==0) { for(int j=0; j<k[i].size(); j++) { add(k[i][j],pos,1); } } while(x%v[i]==0) { x/=v[i]; } } } int main() { sieve(1e6+1); int t,n; scanf("%d",&t); while(t--) { scanf("%d",&n); for(int i=0; i<v.size(); i++) { k[i].clear(); } for(int i=1; i<=n; i++) { scanf("%d",&a[i]); } for(int i=1; i<=n; i++) { char s[2]; scanf("%s",s); if(s[0]=='F') { b[i]=1; } else b[i]=0; } init(n+1); for(int i=1; i<=n; i++) { if(b[i]==1) { df(a[i],i); } } for(int i=1; i<=n; i++) { if(b[i]==0) { df2(a[i],i); } } for(int i=1; i<=n; i++) { if(b[i]==1) { add(0,i,1); } else add(i,n+1,1); } printf("%d\n",n-maxflow(0,n+1)); } return 0; }
C - Intersections
這個傻逼題,看一眼求逆序對,然後隊友告訴我可能點重合,特麼沒寫,後來發現不用管點重合。。。。
以第一排為標號,求逆序對。//我用的是bit 陣列求逆序對
#include<iostream> #include<algorithm> #include<cstring> #include<string> #include<vector> #include<cstdio> #include<cstdlib> #include<cmath> #include<queue> #include<map> #include<set> #include<stack> using namespace std; typedef long long ll; typedef unsigned long long ull; typedef pair<int,int> P; #define bug printf("*********\n"); #define debug(x) cout<<"["<<x<<"]" <<endl; #define mid (l+r)/2 #define chl 2*k+1 #define chr 2*k+2 #define lson l,mid,chl #define rson mid,r,chr #define pb push_back #define mem(a,b) memset(a,b,sizeof(a)); const long long mod=998244353; const int maxn=5e5+5; const int INF=0x7fffffff; const int inf=0x3f3f3f3f; const double eps=1e-8; int a[maxn]; ll bit[maxn+1],n; int sum(int i) { int s=0; while(i>0) { s +=bit[i]; i-=i&-i; } return s; } void add(int i,int x) { while(i<=n) { bit[i]+=x; i+=i&-i; } } int main() { int t; scanf("%d",&t); while(t--) { memset(bit,0,sizeof(bit)); scanf("%d",&n); for(int i=1; i<=n; i++) { int x; scanf("%d",&x); a[x]=i; } ll ans=0; for(int i=1; i<=n; i++) { int x; scanf("%d",&x); ans+=i-1-sum(a[x]); add(a[x],1); } cout<<ans<<endl; } return 0; }
D - Balloons
隨便做
#include<bits/stdc++.h>
#define lson rt<<1
#define rson rt<<1|1
#define fi first
#define se second
#define lowbit(x) (x&(-(x)))
#define mme(a,b) memset((a),(b),sizeof((a)))
#define fuck(x) cout<<"* "<<x<<"\n"
#define iis std::ios::sync_with_stdio(false)
using namespace std;
typedef long long LL;
typedef unsigned long long uLL;
const int N = 1e6 + 7;
const int ME = 1e6 + 7;
const int mod = 1000000007;
const int INF = 0x3f3f3f3f;
int n;
int ar[N];
int main(){
#ifndef ONLINE_JUDGE
#endif
int tim;
scanf("%d",&tim);
while(tim--){
scanf("%d",&n);
int tot=0;
for(int i=0;i<n;++i){
int x;
scanf("%d",&x);
if(x)tot++;
}
printf("%d\n", tot);
}
return 0;
}
E - Maximum Sum
狀壓DP,如果看不出來多去刷一刷狀壓DP的題,和炮兵陣地很像,這題要注意預處理,不然會超時。
#include<iostream>
#include<algorithm>
#include<cstring>
#include<string>
#include<vector>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<queue>
#include<map>
#include<set>
#include<stack>
#include<bitset>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> P;
#define bug printf("*********\n");
#define debug(x) cout<<"["<<x<<"]" <<endl;
#define mid (l+r)/2
#define chl 2*k+1
#define chr 2*k+2
#define lson l,mid,chl
#define rson mid,r,chr
#define pb push_back
#define mem(a,b) memset(a,b,sizeof(a));
const long long mod=998244353;
const int maxn=20;
const int INF=0x7fffffff;
const int inf=0x3f3f3f3f;
const double eps=1e-8;
int dp[20][1<<16];
vector<int> v[1<<16];
void init() {
for(int i=0; i<1<<16; i++) {
if((i&(i<<1))==0) {
for(int j=0; j<1<<16; j++) {
if((j&(j<<1))==0&&(j&(i<<1))==0&&(j&i)==0&&(j&(i>>1))==0) {
v[i].push_back(j);
}
}
}
}
}
int n;
int mp[maxn][maxn];
int tot[20][1<<16];
int main() {
int t;
init();
scanf("%d",&t);
while(t--) {
scanf("%d",&n);
mem(tot,0);
for(int i=0; i<n; i++) {
for(int j=0; j<n; j++) {
scanf("%d",&mp[i][j]);
}
for(int j=0; j<v[0].size(); j++) {
int s=v[0][j],sum=0;
if(s>=1<<n)break;
for(int l=0; l<n; l++) {
if((s>>l)&1) {
sum+=mp[i][l];
}
}
tot[i+1][s]=sum;
// debug(sum);
}
}
int ans=0;
memset(dp,0,sizeof(dp));
for(int l=1; l<=n; l++) {
for(int i=0; v[0].size(); i++) {
int s=v[0][i];
if(s>=1<<n)break;
for(int j=0; j<v[s].size(); j++) {
int target=v[s][j];
if(target>=1<<n)break;
// cout<<s<<" "<<target<<endl;
// debug(tot[l][target]);
dp[l][target]=max(dp[l][target],dp[l-1][s]+tot[l][target]);
// if(target)debug(dp[l][target]);
ans=max(dp[l][target],ans);
}
}
}
cout<<ans<<endl;
}
return 0;
}
F - Working Time
不寫下一個只貼個程式碼了。。。
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <cstring>
#include <cstdio>
#include <string>
#include <cmath>
#include <set>
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
typedef pair<char, int> PCI;
const LL INF = 0x3f3f3f3f;
const LL LLINF = 0x3f3f3f3f3f3f3f3f;
const int MAX_N = (int)2e5+17;
const int MAX_M = (int)2e5+17;
int N, M, S, T, K, tp;
int a[MAX_N], b[MAX_N], lt[MAX_N];
int vis[MAX_N];
int main() {
// freopen("../data.in", "r", stdin);
//ios_base::sync_with_stdio(false);cin.tie(0);
scanf("%d", &T);
int kase = 1;
while (T --) {
scanf("%d %d", &N, &M);
int h = 0,m = 0;
for(int i = 0; i < N; i++) {
int q1,q2,w1,w2;
scanf("%d:%d %d:%d", &q1,&w1,&q2,&w2);
h += q2-q1-1;m += w2 + (60-w1);
}
h += m/60;
if(h >= M) {
printf("YES\n");
} else {
printf("NO\n");
}
}
return 0;
}
G - Hard Equation
擴充套件BSGS模板題
#include<iostream>
#include<algorithm>
#include<cstring>
#include<string>
#include<vector>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<queue>
#include<map>
#include<set>
#include<stack>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define bug printf("*********\n");
#define debug(x) cout<<"["<<x<<"]" <<endl;
#define mid (l+r)/2
#define chl 2*k+1
#define chr 2*k+2
#define lson l,mid,chl
#define rson mid,r,chr
#define pb push_back
#define mem(a,b) memset(a,b,sizeof(a));
const long long mod=998244353;
const int maxn=5e5+5;
const int INF=0x7fffffff;
const int inf=0x3f3f3f3f;
const double eps=1e-8;
typedef long long LL;
inline LL gcd(LL a, LL b) {
return (!b) ? a : gcd(b, a % b);
}
inline void Exgcd(LL a, LL b, LL &d, LL &x, LL &y) {
if (!b) {
d = a, x = 1, y = 0;
} else {
Exgcd(b, a % b, d, y, x), y -= x * (a / b);
}
}
inline LL Solve(LL a, LL b, LL c) {// ax%c=b S.T. (a,c)=1
LL d, x, y;
Exgcd(a, c, d, x, y);
x = (x + c) % c;
return x * b % c;
}
inline LL Ksm(LL x, LL y, LL p) {
LL res = 1, t = x;
for(; y; y >>= 1) {
if (y & 1) res = res * t % p;
t = t * t % p;
}
return res;
}
#define mod 1313131
struct Hashset {
LL head[mod], next[maxn], f[maxn], v[maxn], ind;
void reset() {
ind = 0;
memset(head, -1, sizeof head);
}
void Insert(LL x, LL _v) {
LL ins = x % mod;
for(LL j = head[ins]; j != -1; j = next[j])
if (f[j] == x) {
v[j] = min(v[j], _v);
return;
}
f[ind] = x, v[ind] = _v;
next[ind] = head[ins], head[ins] = ind++;
}
LL operator [] (const LL &x) const {
LL ins = x % mod;
for(LL j = head[ins]; j != -1; j = next[j])
if (f[j] == x)
return v[j];
return -1;
}
} S;
LL BSGS(LL C, LL A, LL B, LL p) {// A^x%p=B S.T.(A,p)=1
if (p <= 100) {
LL d = 1;
for(int i = 0; i < p; ++i) {
if (d == B)
return i;
d = d * A % p;
}
return -1;
} else {
LL m = (int)sqrt(p);
S.reset();
LL d = 1, Search;
for(int i = 0; i < m; ++i) {
S.Insert(d, i);
d = d * A % p;
}
for(int i = 0; i * m < p; ++i) {
d = Ksm(A, i * m, p) * C % p;
Search = S[Solve(d, B, p)];
if (Search != -1)
return i * m + Search;
}
return -1;
}
}
int main() {
LL x, z, k;
register LL i, j;
int t;
scanf("%d",&t);
while(t--) {
scanf("%I64d%I64d%I64d", &x, &k, &z);
LL d = 1;
bool find = 0;
for(i = 0; i < 100; ++i) {
if (d == k) {
printf("%I64d\n", i);
find = 1;
break;
}
d = d * x % z;
}
if (find)
continue;
LL t, C = 1, num = 0;
bool failed = 0;
while((t = gcd(x, z)) != 1) {
z /= t;
k /= t;
C = C * x / t % z;
++num;
}
LL res = BSGS(C, x, k, z);
if (res == -1)
puts("No Solution");
else
printf("%I64d\n", res + num);
}
return 0;
}
H | Gym 101853H |
I | Gym 101853I |
答案。。。d*d/2
J | Gym 101853J |
這3題就不貼程式碼了。水題(其實是懶得寫。。。。。)
K - Citations
慢慢模擬
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <cstring>
#include <cstdio>
#include <string>
#include <cmath>
#include <set>
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
typedef pair<char, int> PCI;
const LL INF = 0x3f3f3f3f;
const LL LLINF = 0x3f3f3f3f3f3f3f3f;
const int MAX_N = (int)2e5+17;
const int MAX_M = (int)2e5+17;
int N, M, S, T, K, tp;
int a[MAX_N], b[MAX_N], lt[MAX_N];
int vis[MAX_N];
char s[21][322];
int main() {
scanf("%d", &T);
int kase = 1;
while (T--) {
scanf("%d", &N);getchar();
while(N--) {
for(int i = 0; i < 10; i++) {
fgets(s[i], sizeof(s[i]), stdin);
//printf("%s",s[i]);
}
for(int i = 1; i <= 8; i++) {
if(s[i][0]=='a') {
vector<char> v;v.clear();
for(int j = 8; ; ) {
v.push_back(s[i][j]);
v.push_back(s[i][j+1]);
while(s[i][j] != ' ') j++;j++;
v.push_back(s[i][j]);
while(s[i][j] != ',' && s[i][j] != '}') j++;
if(s[i][j] == '}') break;
else j += 2;
}
for(int j = 0; j < v.size(); j+=3) {
printf("%c%c. %c%c ",v[j],v[j+1],v[j+2],(j+3<v.size())?',':'.');
}
break;
}
}
for(int i = 1; i <= 8; i++) {
if(s[i][0]=='t') {
for(int j = 7; s[i][j] != '}'; j++) {
printf("%c",s[i][j]);
}
printf(". ");
break;
}
}
for(int i = 1; i <= 8; i++) {
if(s[i][0]=='j') {
for(int j = 9; s[i][j] != '}'; j++) {
printf("%c",s[i][j]);
}
printf(". ");
break;
}
}
for(int i = 1; i <= 8; i++) {
if(s[i][0]=='y') {
for(int j = 6; s[i][j] != '}'; j++) {
printf("%c",s[i][j]);
}
printf(";");
break;
}
}
for(int i = 1; i <= 8; i++) {
if(s[i][0]=='v') {
for(int j = 8; s[i][j] != '}'; j++) {
printf("%c",s[i][j]);
}
printf("(");
break;
}
}
for(int i = 1; i <= 8; i++) {
if(s[i][0]=='n') {
for(int j = 8; s[i][j] != '}'; j++) {
printf("%c",s[i][j]);
}
printf("):");
break;
}
}
for(int i = 1; i <= 8; i++) {
if(s[i][0]=='p' && s[i][1]=='a') {
for(int j = 7; s[i][j] != '}'; j++) {
printf("%c",s[i][j]);
}
printf(".\n");
break;
}
}
}
}
return 0;
}