C - Make it Simple https://atcoder.jp/contests/abc393/tasks/abc393_c
这一题想要把一个无向图变成简单图,我说实话就是用set数组直接存边,同时不存自循环边,最后再把边数之差算出来就行了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 #include <bits/stdc++.h> using namespace std;using u32 = unsigned ;#define i128 __int128; using ll = long long ;using u64 = unsigned long long ;const ll inf = 1e9 ;const ll INF = 1e18 ;signed main () { ios::sync_with_stdio (false ); cin.tie (nullptr ); int n,m; cin>>n>>m; set<int >s[n+1 ]; int cnt=0 ; for (int i=1 ;i<=m;i++) { int u,v; cin>>u>>v; if (u==v)continue ; s[u].insert (v); s[v].insert (u); } for (int i=1 ;i<=n;i++) { cnt+=s[i].size (); } cnt/=2 ; int ret=m-cnt; cout<<ret<<'\n' ; return 0 ; }
D - Swap to Gather https://atcoder.jp/contests/abc393/tasks/abc393_d
方法一 (我的) 我的这个方法比较蠢,但是确实想到的比较快。
就是首先进行预处理,然后枚举所有位置,然后让左右两边的1往这个位置上靠,不断更新最终的结果ans。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 #include <bits/stdc++.h> using namespace std;using u32 = unsigned ;#define i128 __int128; using ll = long long ;#define int ll using u64 = unsigned long long ;const ll inf = 1e9 ;const ll INF = 1e18 ;signed main () { ios::sync_with_stdio (false ); cin.tie (nullptr ); int n; cin>>n; string s; cin>>s; s=" " +s; vector<int >pre (n+1 ),precnt (n+1 ),suf (n+2 ),sufcnt (n+2 ); for (int i=1 ;i<=n;i++) { pre[i]=pre[i-1 ]+(s[i]=='1' ?i:0 ); precnt[i]=precnt[i-1 ]+(s[i]=='1' ?1 :0 ); } for (int i=n;i>=1 ;i--) { suf[i]=suf[i+1 ]+(s[i]=='1' ?i:0 ); sufcnt[i]=sufcnt[i+1 ]+(s[i]=='1' ?1 :0 ); } int ans=LLONG_MAX; for (int i=1 ;i<=n;i++) { int ret1=0 ,ret2=0 ; ret1=1ll *i*precnt[i]-pre[i]-1ll *(precnt[i]-1 )*precnt[i]/2 ; ret2=suf[i+1 ]-1ll *(i+1 )*sufcnt[i+1 ]-1ll *(sufcnt[i+1 ]-1 )*sufcnt[i+1 ]/2 ; ans=min (ans,ret1+ret2); } cout<<ans<<'\n' ; return 0 ; }
官方解法(很妙) ==官方做法:== 我们先考虑某一个0:如果它左侧的1比较少,那么应该将其移动至其左侧所有1的左侧;如果它右侧的1比较少,那么应该将其移动至其右侧所有1的右侧,因此对于每个0,它的代价都是:min(左侧的1的个数,右侧的1的个数)答案即为所有0的代价的和、
这个方法太妙了,比我的傻鸟预处理好多了。他是将每一个1进行移动,然后每一步都很好写,但是我的就是同时移动所有的1,虽然感觉我的复杂度也不是很高。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 #include <bits/stdc++.h> using namespace std;using u32 = unsigned ;#define i128 __int128; using ll = long long ;#define int ll using u64 = unsigned long long ;const ll inf = 1e9 ;const ll INF = 1e18 ;signed main () { ios::sync_with_stdio (false ); cin.tie (nullptr ); int n; cin >> n; string s; cin >> s; int sum = 0 ; for (auto ch : s) { if (ch == '1' ) sum++; } int ans = 0 ; int cnt = 0 ; for (int i = 0 ; i < n; i++) { if (s[i] == '0' ) { ans += min (cnt, sum - cnt); } else { cnt++; } } cout << ans << '\n' ; return 0 ; }
E - GCD of Subset 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 #include <bits/stdc++.h> using namespace std;using u32 = unsigned ;#define i128 __int128; using ll = long long ;using u64 = unsigned long long ;const ll inf = 1e9 ;const ll INF = 1e18 ;const int N=1200010 ;const int MAXN=1000010 ;int n,k;int a[N];int cnt[MAXN];int multi[MAXN];int ans[MAXN];signed main () { ios::sync_with_stdio (false ); cin.tie (nullptr ); cin>>n>>k; int maxn=0 ; for (int i=1 ;i<=n;i++) { cin>>a[i]; maxn=max (maxn,a[i]); cnt[a[i]]++; } for (int x=1 ;x<=maxn;x++) { for (int y=x;y<=maxn;y+=x) { multi[x]+=cnt[y]; } } for (int i=1 ;i<=maxn;i++) { if (multi[i]<k)continue ; for (int j=i;j<=maxn;j+=i) { ans[j]=max (ans[j],i); } } for (int i=1 ;i<=n;i++) { cout<<ans[a[i]]<<'\n' ; } return 0 ; }