2020 ICPC 上海赛区
赛时6题。第七题我写的没de出来(给队友跪了)
xixike哥太强了有5题代码都是他写的(我只写了半题)
ggxxdd哥也非常强特别会数学题。
只有我什么都不会
G,B
都是队友切的签到,没看
M:
虽然会有重复的,但只要把前缀一起放到map里去就不会有任何重复的点因此可以打标记,这样就能建树了。然后就是dfs如果子树全被删除了该父节点就可以删除,否则就只能挨个删子节点。
我写了建树的部分,队友写的dfs
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 1e5 + 10;
string s[105];
vector<int>E[10005];
int k;
bool vis[10005];
map<string,int>mp;
int ans=0;
int siz[N], num[N];
void dfs(int x){
    // cout << "dfs " << x << endl;
    if(vis[x]) num[x] = 1;
    if(!E[x].size()) siz[x] = 1;
    for(auto y : E[x]){
        dfs(y);
        siz[x] += siz[y], num[x] += num[y];
    }    
    return;
}
inline void get_ans(int x){
    // cout << "x " << x << " " << num[x] << " " << siz[x] << endl;
    if(x > 1 && num[x] == siz[x]) return ans++, void();
    for(auto y : E[x]) get_ans(y);
}
void solve(){
    mp.clear();k=0,ans=0;
    int n,m;cin>>n>>m;
    for(int i = 1; i <= n + m; ++i) cin >> s[i];
    // sort(s + 1, s + 1 + n + m);
    // for(int i=1;i<=n;i++)cin>>s[i];
    // for(int j=1;j<=m;j++)cin>>s[j+n];
    mp["0"] = ++k;
    for(int i=1;i<=n+m;i++){
        string tmp="",s1="0";
        for(int j=0;j<=(int)s[i].size();j++){
            if(s[i][j]=='/'||j==s[i].size()){
                string s2=s1;
                if(!mp[s1]) mp[s1] = ++k;
                s1 = s1 + '/' + tmp;
                tmp="";
                if(mp[s1] && mp[s2]) continue;
                if(!mp[s1]) mp[s1]=++k;
                // cout<<s1<<"\n";
                E[mp[s2]].push_back(mp[s1]);
                // cout << "add " << i << " " << j << "  " << s2 << "   " << s1 << endl;
                if(j==s[i].size()&&i<=n)vis[mp[s1]]=1;
            }
            else{
                tmp+=s[i][j];
            }
        }
    }
    dfs(1), get_ans(1);
    cout<<ans<<"\n";
    for(int i=1;i<=k;i++)E[i].clear(),vis[i]= num[i] = siz[i] = 0;
}
signed main(){
#ifndef ONLINE_JUDGE
    freopen("test.in", "r", stdin);
    freopen("test.out", "w", stdout);
#endif
    int tt;cin>>tt;while(tt--){
        solve();
    }
}
D:
二分题。但是wa6,因为少考虑了第三种情况。。。
I:
考虑出在一个圆上应该如何走即可解决。
C:
据队友说是数位dp加上一些别的但是总之我不会
H:
赛时写完了没de完。思路队友切的。分为两段。
1.观察到把人和菜分别连线不会出现交叉的情况,所以可以枚举匹配
2.桌子最多只会调换一次方向
#include <bits/stdc++.h>
#include <algorithm>
#include <cmath>
using namespace std;
const int N = 1e3 + 500;
int n, k, a[N], b[N],p2[N],p1[N];
int disr(int x,int y){
	return (x-y+n)%n;
}
int disl(int x,int y){
	return (y-x+n)%n;
}
bool cmp1(const int &x, const int &y) {
	return disl(a[x],b[p1[x]])<disl(a[y],b[p1[y]]);
}
bool cmp2(int x,int y){
	return disr(a[x],b[p1[x]])<disr(a[y],b[p1[y]]);
}
void solve() {
    cin >> n >> k;
    for (int i = 0; i < k; i++)cin >> a[i];
    for (int i = 0; i < k; i++)cin >> b[i];
    sort(a , a  + k);
    sort(b , b  + k);
    int ans=0x3f3f3f3f;
    for(int j=0;j<k;j++)p2[j]=j;
    for(int i=0;i<k;i++){
    	for(int j=0;j<k;j++){
    		p1[j]=(i+j)%k;
		}
		//left
		sort(p2,p2+k,cmp1);
		ans=min(ans,disl(a[p2[k-1]],b[p1[p2[k-1]]]));
		int mx=0;
		for(int j=k-2;j>=0;j--){
			int pos=disl(a[p2[j]],b[p1[p2[j]]]);
			mx=max(mx,disr(a[p2[j+1]],b[p1[p2[j+1]]]));
			ans=min(ans,mx+pos*2);
		}
		//right
		sort(p2,p2+k,cmp2);
		ans=min(ans,disr(a[p2[k-1]],b[p1[p2[k-1]]]));
		mx=0;
		for(int j=k-2;j>=0;j--){
			int pos=disr(a[p2[j]],b[p1[p2[j]]]);
			mx=max(mx,disl(a[p2[j+1]],b[p1[p2[j+1]]]));
			ans=min(ans,mx+pos*2);
		}
	}
	cout<<ans<<endl;
}
int main() {
    int t;
    cin >> t;
    for (int i = 1; i <= t; i++) {
        solve();
    }
}
E:
dp递推,每次最小的数必须放在前k个
如果能观察出1应该如何放的话其实不难想到怎么dp。。
式子需要稍微推一下就可以O(n)
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int maxn=1e7+10,mod=998244353;
int dp[maxn],inv[maxn];
void solve() {
    int n,k;cin>>n>>k;
    inv[0]=1;inv[1]=1;
    for(int i=2;i<=n;i++)inv[i]=(mod-mod/i)*inv[mod%i]%mod;
    int sum=1;
    dp[0]=1;
    for(int i=1;i<=n;i++){
    	dp[i]=sum*inv[i]%mod;
    	sum=(sum+dp[i])%mod;
    	if(i>=k)sum=(sum+mod-dp[i-k])%mod;
	}
	for(int i=2;i<=n;i++)dp[n]=dp[n]*i%mod;
	cout<<dp[n]<<endl;
}
signed main() {
    int t=1;
    //cin >> t;
    for (int i = 1; i <= t; i++) {
        solve();
    }
}
L:
其他题过的人没上百就不补了,收工
                    
                
                
            
        
浙公网安备 33010602011771号