D - ABC Transform
Meaning:
Given a string containing ABC, one character will become two characters for each extension.
A →BC, B →CA, C →AB.
Q times of inquiry, after ti times of expansion, what is the ki character?
Q ≤10^5, ti<10^18, ki<min(1e18, the length of S(t))
Idea:
For a higher number of layers, each time the path is found, it is like a complete binary tree. For the x-th node of the current layer, its parent node is the X / 2 (rounded up) of the previous layer.
Because x will not exceed 1e18, so divide by 2 every time, and it will become 1 no more than 64 times. After it becomes 1, its ancestor node will be 1. Because the first position is cyclic, take the module directly to see what the current node is, and then go back according to the path.
Code:
const int N = 200010, mod = 1e9+7; int T, n, m, k; char a[N]; int b[N]; signed main(){ Ios; cin>>a+1; n = strlen(a+1); mp['A'] = {'B', 'C'}, mp['B'] = {'C', 'A'}, mp['C'] = {'A', 'B'}; cin>>m; while(m--) { int floor, cnt; cin>>floor>>cnt; int id; if(floor>=60) id=1; else { int x = 1ll<<floor; id = (cnt+x-1)/x; if(cnt%x==0) cnt=x; else cnt%=x; } int t=0; while(cnt!=1) { b[++t] = cnt%2; cnt = (cnt+1)/2; floor--; } char st; if(floor%3==0) st = a[id]; if(floor%3==1){st = char(a[id]+1);if(st=='D') st='A';} if(floor%3==2){st = char(a[id]+2);if(st=='D') st='A';if(st=='E') st='B';} for(int i=t;i>=1;i--) { if(b[i]==0) st = mp[st].se; else st = mp[st].fi; } cout << st << endl; } return 0; }
D. Make Them Equal
Meaning:
Given an array a with a length of n(1 ≤ n ≤ 10 ^ 3), it is initially all 1 and can undergo up to k operations:
For an i, select an x, and ai is updated to ai+ai/x.
If it becomes ai==bi, you will get ci gold coins. 1 ≤bi ≤10^3,0 ≤k ≤10^6
How many gold coins can you get at most?
Idea:
dp preprocesses the minimum operand that changes from 1 to x, and then converts it into n items. Each item has value and cost,
Find the maximum total value that the cost does not exceed k. But the double loop will time out.
Finally, it is found that the maximum minimum operand will not exceed 12, so the cost will not exceed 13*n, so it can be passed.
dp processing:
Traverse each number from small to large, and update the status of the later larger number with the current number + factor;
Code:
const int N = 200010, mod = 1e9+7; int T, n, m, k; int a[N], cost[N]; int dp[1010][13010], w[N]; signed main(){ Ios; for(int i=2;i<=1000;i++) cost[i]=1e9; for(int i=1;i<=1000;i++) { for(int j=1;j<=i;j++) { int t = i/j; cost[i+t] = min(cost[i+t], cost[i]+1); } } cin>>T; while(T--) { cin>>n>>m; m = min(m, 13*n); for(int i=1;i<=n;i++) { int x;cin>>x; a[i] = cost[x]; } for(int i=1;i<=n;i++) cin>>w[i]; for(int i=1;i<=n;i++) { for(int j=0;j<=m;j++) dp[i][j]=dp[i-1][j]; for(int j=a[i];j<=m;j++) { dp[i][j] = max(dp[i-1][j], dp[i-1][j-a[i]]+w[i]); } } cout << dp[n][m] << endl; } return 0; }
C. Weird Sum
Meaning:
Find the sum of Hamiltonian distances of all points with the same color in a matrix.
Idea:
Hamiltonian distance can be decomposed into two one-dimensional problems.
Find the sum of the distances between all points of the same kind, and use the cells between two adjacent points.
Code:
const int N = 200010, mod = 1e9+7; int T, n, m, k; int a[N]; vector<int> v1[N], v2[N]; signed main(){ Ios; cin>>n>>m; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++){ int x;cin>>x; v1[x].pb(i), v2[x].pb(j); } int ans=0; for(int i=1;i<=100000;i++) { if(v1[i].size()==0) continue; int n = v1[i].size()-1; for(int j=0;j<n;j++) { ans += (v1[i][j+1]-v1[i][j])*((j+1)*(n-j)); } } for(int i=1;i<=100000;i++) { sort(v2[i].begin(), v2[i].end()); if(v2[i].size() == 0) continue; int n = v2[i].size()-1; for(int j=0;j<n;j++) { ans += (v2[i][j+1]-v2[i][j])*((j+1)*(n-j)); } } cout << ans; return 0; }
D. Integral Array
Meaning:
Given n numbers, judge whether the following conditions are met:
Select two numbers x ≥ y (which can be the same), and x/y is also in these n numbers.
n ≤10^6, maxa ≤10^6.
Idea:
Traverse each number x, enumerate its multiple y, and judge whether there are numbers in the set (prefix and judgment) in the interval [y, y+x-1], and y/x does not exist.
Code:
const int N = 2000010, mod = 1e9+7; int T, n, m, k; int a[N], s[N], t[N]; set<int> st; bool mp[N]; signed main(){ Ios; cin>>T; while(T--) { cin>>n>>m; st.clear(); for(int i=1;i<=n;i++){ cin>>t[i]; int x = t[i]; a[x]++, mp[x]=1; st.insert(x); } for(int i=1;i<=m;i++) s[i] = s[i-1]+a[i]; int flag=0; if(*st.begin() != 1) flag=1; for(auto x:st) { for(int j=x;j<=m;j+=x) { if(s[min(j+x-1, m)] - s[j-1] > 0 && !mp[j/x]) flag=1; } } for(int i=1;i<=m;i++) a[i] = mp[i] = 0; if(flag) cout<<"No\n"; else cout<<"Yes\n"; } return 0; }