​A - Bitwise Exclusive Or​
  • 水题
  • 代码:
    #include <bits/stdc++.h> #define ll long long #define fi first #define se second #define pb push_back #define me memset #define rep(a,b,c) for(int a=b;a<=c;++a) #define per(a,b,c) for(int a=b;a>=c;--a) const int N = 1e6 + 10; const int mod = 1e9 + 7; const int INF = 0x3f3f3f3f; using namespace std; typedef pair<int,int> PII; typedef pair<ll,ll> PLL; ll gcd(ll a,ll b) {return b?gcd(b,a%b):a;} ll lcm(ll a,ll b) {return a/gcd(a,b)*b;} int main() { ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); int a,b; cin>>a>>b; cout<<(a^b)<<'\n'; return 0; }
​B - Booby Prize​
  • 水题
  • 代码:
    #include <bits/stdc++.h> #define ll long long #define fi first #define se second #define pb push_back #define me memset #define rep(a,b,c) for(int a=b;a<=c;++a) #define per(a,b,c) for(int a=b;a>=c;--a) const int N = 1e6 + 10; const int mod = 1e9 + 7; const int INF = 0x3f3f3f3f; using namespace std; typedef pair<int,int> PII; typedef pair<ll,ll> PLL; ll gcd(ll a,ll b) {return b?gcd(b,a%b):a;} ll lcm(ll a,ll b) {return a/gcd(a,b)*b;} int main() { ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); int n; cin>>n; vector<PII> a(n+1); rep(i,1,n){ cin>>a[i].fi; a[i].se=i; } sort(a.begin()+1,a.end()); cout<<a[n-1].se<<'\n'; return 0; }
​ C - Reorder Cards​
  • 题意:给你一个\(n\)x\(m\)的空矩阵,将矩阵的\(n\)个点标记,然后删除所有没有任何标记的整行和整列,问原标记的点在新矩阵中的位置.
  • 题解:将标记的点的坐标存到两个vector中然后离散化直接输出下标即可.
  • 代码:
    #include <bits/stdc++.h> #define ll long long #define fi first #define se second #define pb push_back #define me memset #define rep(a,b,c) for(int a=b;a<=c;++a) #define per(a,b,c) for(int a=b;a>=c;--a) const int N = 1e6 + 10; const int mod = 1e9 + 7; const int INF = 0x3f3f3f3f; using namespace std; typedef pair<int,int> PII; typedef pair<ll,ll> PLL; ll gcd(ll a,ll b) {return b?gcd(b,a%b):a;} ll lcm(ll a,ll b) {return a/gcd(a,b)*b;} int h,w,n; int a[N],b[N]; unordered_map<int,int> mp1,mp2; int main() { ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); cin>>h>>w>>n; vector<int> row,col; rep(i,1,n){ cin>>a[i]>>b[i]; if(!mp1[a[i]]) row.pb(a[i]); if(!mp2[b[i]]) col.pb(b[i]); mp1[a[i]]++; mp2[b[i]]++; } sort(row.begin(),row.end()); sort(col.begin(),col.end()); rep(i,1,n){ int x=upper_bound(row.begin(),row.end(),a[i])-row.begin(); int y=upper_bound(col.begin(),col.end(),b[i])-col.begin(); cout<<x<<' '<<y<<'\n'; } return 0; }
​D - Takahashi Tour​
  • 题意:有\(n\)个点,\(n-1\)条边,从第一个点\(1\)开始走,每次选择没有访问的最小的点走,如果出边均访问过,则返回上一个点,直到返回到\(1\)且无路可走时停止,按顺序输出走过的路径。
  • 题解:直接dfs模拟即可。
  • 代码:
    #include <bits/stdc++.h> #define ll long long #define fi first #define se second #define pb push_back #define me memset #define rep(a,b,c) for(int a=b;a<=c;++a) #define per(a,b,c) for(int a=b;a>=c;--a) const int N = 1e6 + 10; const int mod = 1e9 + 7; const int INF = 0x3f3f3f3f; using namespace std; typedef pair<int,int> PII; typedef pair<ll,ll> PLL; ll gcd(ll a,ll b) {return b?gcd(b,a%b):a;} ll lcm(ll a,ll b) {return a/gcd(a,b)*b;} int n; int u,v; vector<int> edge[N]; bool vis[N]; vector<int> ans; void dfs(int u){ ans.pb(u); vis[u]=true; for(auto to:edge[u]){ if(!vis[to]){ dfs(to); ans.pb(u); } } if(u==1) return; } int main() { ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); cin>>n; rep(i,1,n-1){ cin>>u>>v; edge[u].pb(v); edge[v].pb(u); } rep(i,1,n){ sort(edge[i].begin(),edge[i].end()); } dfs(1); for(auto w:ans) cout<<w<<' '; return 0; }
​E - Stronger Takahashi​
  • 题意:有\(n\)x\(m\)的网格图,#表示不能走,.表示能走,初始位置在\((1,1)\),每次可以向下或者向右走,你可以使用\(1\)点力量是的图中任意位置的一个\(2\)x\(2\)的子矩阵变为\(.\),问你最少使用多少能量才能走到右下角\((n,m)\).
  • 题解:使用01-BFS,首先上下左右四个方向,如果能走,也就代表没有花费,那么可以看成边权为\(0\),然后更新距离,push_front(),再看周围相邻的\(2\)x\(2\)的矩阵,一共\(20\)个方向,我们花费\(1\)个贡献,这些点都能走到,那么就看成边权是\(1\),更新距离再push_back()即可.
  • 代码:
    #include <iostream> #include <iomanip> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <stack> #include <queue> #include <vector> #include <map> #include <set> #include <unordered_set> #include <unordered_map> #define ll long long #define db double #define fi first #define se second #define pb push_back #define me memset #define rep(a,b,c) for(int a=b;a<=c;++a) #define per(a,b,c) for(int a=b;a>=c;--a) const int N = 1e6 + 10; const int mod = 1e9 + 7; const int INF = 0x3f3f3f3f; using namespace std; typedef pair<int,int> PII; typedef pair<ll,ll> PLL; int gcd(int a,int b){return b?gcd(b,a%b):a;} int lcm(int a,int b){return a/gcd(a,b)*b;} int n,m; char s[505][505]; bool vis[505][505]; int dis[505][505]; int f_dx[]={-1,0,1,0},f_dy[]={0,1,0,-1}; int c_dx[]={-1,-2,-1,-2,0,0,1,2,1,2,1,2,0,0,-1,-2,-1,1,1,-1},c_dy[]={0,0,1,1,1,2,1,1,0,0,-1,-1,-1,-2,-1,-1,2,2,-2,-2}; deque<PII> dq; int main() { ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #ifdef lr001 freopen("/Users/somnus/Desktop/data/in.txt","r",stdin); #endif #ifdef lr002 freopen("/Users/somnus/Desktop/data/out.txt","w",stdout); #endif cin>>n>>m; me(dis,INF,sizeof(dis)); for(int i=1;i<=n;++i){ for(int j=1;j<=m;++j){ cin>>s[i][j]; } } dq.push_back({1,1}); dis[1][1]=0; while(!dq.empty()){ auto tmp=dq.front(); dq.pop_front(); int x=tmp.fi,y=tmp.se; if(vis[x][y]) continue; vis[x][y]=true; for(int i=0;i<4;++i){ int tx=x+f_dx[i]; int ty=y+f_dy[i]; if(tx>=1 && tx<=n && ty>=1 && ty<=m && s[tx][ty]=='.' && dis[tx][ty]>dis[x][y]){ dis[tx][ty]=dis[x][y]; dq.push_front({tx,ty}); } } for(int i=0;i<20;++i){ int tx=x+c_dx[i]; int ty=y+c_dy[i]; if(tx>=1 && tx<=n && ty>=1 && ty<=m && dis[tx][ty]>dis[x][y]+1){ dis[tx][ty]=dis[x][y]+1; dq.push_back({tx,ty}); } } } cout<<dis[n][m]<<'\n'; return 0; }
​F - Common Prefixes​
  • 题意:有一长度为\(n\)的字符串\(S\),\(S_i\)表示从\(i\)到\(n\)的后缀\(S_{i...n}\),\(f(S_i,S_j)\)表示后缀\(S_i\)和\(S_j\)的最长公共前缀,求对于每个\(k=1,2,...,n\),\(Sum_k=f(S_k,S_1)+f(S_k,S_2)+...+f(S_k,S_n)\)的值。
  • 题解:先用后缀数组处理出\(sa\)和\(height\)数组,这个不难,关键是我们要怎么在\(O(n)\)的时间内求出\(\sum_{j=1}^{n}min^{max(i,j)}_{k=min(i,j)}height_k\). 稍后待补。。。。。。。。。。。。。。
  • 代码:
    #include <bits/stdc++.h> #define ll long long #define fi first #define se second #define pb push_back #define me memset #define rep(a,b,c) for(int a=b;a<=c;++a) #define per(a,b,c) for(int a=b;a>=c;--a) const int N = 1e6 + 10; const int mod = 1e9 + 7; const int INF = 0x3f3f3f3f; using namespace std; typedef pair<int,int> PII; typedef pair<ll,ll> PLL; ll gcd(ll a,ll b) {return b?gcd(b,a%b):a;} ll lcm(ll a,ll b) {return a/gcd(a,b)*b;} int n,m; string s; int sa[N],x[N],y[N],c[N],rk[N],height[N]; void get_sa(){ for(int i=1;i<=n;++i) c[x[i]=s[i]]++; for(int i=2;i<=m;++i) c[i]+=c[i-1]; for(int i=n;i;i--) sa[c[x[i]]--]=i; for(int k=1;k<=n;k<<=1){ int num=0; for(int i=n-k+1;i<=n;++i) y[++num]=i; for(int i=1;i<=n;++i){ if(sa[i]>k) y[++num]=sa[i]-k; } for(int i=1;i<=m;++i) c[i]=0; for(int i=1;i<=n;++i) c[x[i]]++; for(int i=2;i<=m;++i) c[i]+=c[i-1]; for(int i=n;i;--i) sa[c[x[y[i]]]--]=y[i],y[i]=0; swap(x,y); x[sa[1]]=1,num=1; for(int i=2;i<=n;++i){ x[sa[i]]=(y[sa[i]]==y[sa[i-1]] && y[sa[i]+k]==y[sa[i-1]+k])?num:++num; } if(num==n) break; m=num; } } void get_height(){ for(int i=1;i<=n;++i) rk[sa[i]]=i; for(int i=1,k=0;i<=n;++i){ if(rk[i]==1) continue; if(k) k--; int j=sa[rk[i]-1]; while(i+k<=n && j+k<=n && s[i+k]==s[j+k]) k++; height[rk[i]]=k; } } int stk[N],top; ll ans[N]; int main() { ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); cin>>n; cin>>s; m=122; s=" "+s; get_sa(); get_height(); stk[0]=1; ll res=0; for(int i=2;i<=n;++i){ while(top && height[stk[top]]>=height[i]){ res-=1ll*(stk[top]-stk[top-1])*height[stk[top]]; top--; } res+=1ll*(i-stk[top])*height[i],stk[++top]=i; ans[sa[i]]+=res; } res=0; top=0; stk[0]=n+1; for(int i=n;i>=1;--i){ ans[sa[i]]+=res+n-sa[i]+1; if(i==1) continue; while(top && height[stk[top]]>=height[i]){ res-=1ll*(stk[top-1]-stk[top])*height[stk[top]]; top--; } res+=1ll*(stk[top]-i)*height[i],stk[++top]=i; } for(int i=1;i<=n;++i) cout<<ans[i]<<'\n'; return 0; }


???????????????????????????????????????????? ???????????????????????????????? ???????????? ???????????????? ???????????????? ???????????????????????????????? ???????? ????????????????