A.要求坐标差为移动距离的两倍。
#include<bits/stdc++.h> using namespace std; int main() { ios::sync_with_stdio(0); int x1,x2,y1,y2,x,y; cin >> x1 >> y1 >> x2 >> y2 >> x >> y; int xx = abs(x1-x2),yy = abs(y1-y2); if(xx%x || yy%y) { cout << "NO" << endl; return 0; } if(xx/x%2 == yy/y%2) cout << "YES" << endl; else cout << "NO" << endl; return 0; }
B.分4种情况分别计算。
#include<bits/stdc++.h> using namespace std; int n,a[100005]; int main() { ios::sync_with_stdio(0); cin >> n; for(int i = 1;i <= n;i++) cin >> a[i]; sort(a+1,a+1+n); int num = 1,cnt = 0; if(a[2] != a[1]) num++; if(a[3] != a[2]) num++; if(num == 1) { for(int i = 1;i <= n;i++) { if(a[i] == a[1]) cnt++; } cout << (long long)cnt*(cnt-1)*(cnt-2)/6 << endl; } else if(num == 2 && a[2] != a[1]) { for(int i = 1;i <= n;i++) { if(a[i] == a[2]) cnt++; } cout << (long long)cnt*(cnt-1)/2 << endl; } else { for(int i = 1;i <= n;i++) { if(a[i] == a[3]) cnt++; } cout << cnt << endl; } return 0; }
C.若x符合,则x+1肯定符合,可以二分最小的x。
#include<bits/stdc++.h> using namespace std; long long n,s; bool ok(long long x) { long long t = x; while(t) { x -= t%10; t /= 10; } if(x >= s) return 1; return 0; } int main() { ios::sync_with_stdio(0); cin >> n >> s; long long l = 1,r = n+1; while(l < r) { long long mid = (l+r)/2; if(ok(mid)) r = mid; else l = mid+1; } cout << n-l+1 << endl; return 0; }
D.l[i]表示i坐标第一个大于等于a[i]的位置,r[i]表示r右边第一个大于a[i]的位置,这样a[i]被当作max算的次数可以求出。减min只要把每个位置的数取负做相同操作。
#include<bits/stdc++.h> using namespace std; int n,a[1000005],l[1000005],r[1000005]; long long ans = 0; void f() { for(int i = 1;i <= n;i++) { l[i] = i-1; while(l[i] >= 1 && a[i] > a[l[i]]) l[i] = l[l[i]]; } for(int i = n;i >= 1;i--) { r[i] = i+1; while(r[i] <= n && a[i] >= a[r[i]]) r[i] = r[r[i]]; } for(int i = 1;i <= n;i++) ans += (long long)(r[i]-i)*(i-l[i])*a[i]; } int main() { ios::sync_with_stdio(0); cin >> n; for(int i = 1;i <= n;i++) cin >> a[i]; f(); for(int i = 1;i <= n;i++) a[i] = -a[i]; f(); cout << ans << endl; return 0; }
E.01异或trie树,把每个数按位分。
#include<bits/stdc++.h> using namespace std; int n,tr[2000005][2] = {0},cnt[2000005],sz = 0; void add(int x,int v) { int now = 0; for(int i = 30;i >= 0;i--) { int t = bool((1<<i)&x); if(!tr[now][t]) tr[now][t] = ++sz; now = tr[now][t]; cnt[now] += v; } } int getsum(int x,int y) { int now = 0,ans = 0; for(int i = 30;i >= 0;i--) { int xt = bool((1<<i)&x),yt = bool((1<<i)&y); if(!yt && !tr[now][xt]) break; if(!yt) now = tr[now][xt]; else { if(tr[now][xt]) ans += cnt[tr[now][xt]]; if(!tr[now][!xt]) break; now = tr[now][!xt]; } } return ans; } int main() { ios::sync_with_stdio(0); cin >> n; while(n--) { int x,y,z; cin >> x >> y; if(x == 1) add(y,1); else if(x == 2) add(y,-1); else { cin >> z; cout << getsum(y,z) << endl; } } return 0; }