2019-2020nowcoder牛客寒假基础4
A欧几里得
1 0
2 1
3 2
第一个数字是上一行数字的和,第二个数字是上一行数字第一个数字
#include <cstdio> #include <cmath> #include <algorithm> #include <iostream> #include <cstring> #include <queue> #include <set> #include <map> #include <stack> using namespace std; #define scd(a) scanf("%d",&a) #define scdd(a,b) scanf("%d%d",&a,&b) #define scddd(a,b,c) scanf("%d%d%d",&a,&b,&c) #define scl(a) scanf("%lld",&a) #define scll(a,b) scanf("%lld%lld",&a,&b) #define sclll(a,b,c) scanf("%lld%lld%lld",&a,&b,&c) #define prl(a) printf("%lld\n",a) #define prd(a) printf("%d\n",a) #define prf(a) printf("%lf\n",a) #define ptd(a) printf("%d ",a) #define scf(a) scanf("%lf",&a) #define scff(a,b) scanf("%lf%lf",&a,&b) #define scfff(a,b,c) scanf("%lf%lf%lf",&a,&b,&c) #define rint register int #define mem(a) memset(a,0,sizeof(a)) #define rush() int T;scd(T);while(T--) #define lc(i) (i<<1) #define rc(i) (i<<1|1) #define mp make_pair #define lowbit(x) (x&(-x)) #define For(i,st,en) for(int i=st;i<en;++i) #define SZ(x) ((int)(x).size()) #define ALL(x) (x).begin(), (x).end() template<typename S, typename T> inline bool Min(S &a, const T &b){ return a > b ? a = b, true : false; } template<typename S, typename T> inline bool Max(S &a, const T &b){ return a < b ? a = b, true : false; } typedef long long ll; typedef double db; inline int read() {char c=getchar();int x=0,f=1;while(c<'0'||c>'9') {if(c=='-')f=-1;c=getchar();}while(c>='0'&&c<='9') {x=x*10+c-'0';c=getchar();}return x*f;} const ll mod = 1e9 + 7; const int maxn = 1e5 + 10; int main () { ll dp[82]; dp[0]=1;//1 0 dp[1]=3;//2 1 dp[2]=5;//3 2 //dp[3] 5 3 For(i,3,82)dp[i]=dp[i-1]+dp[i-2]; rush(){ prl(dp[read()]); } return 0; }
B括号序列
stack水过去就好了
#include <cstdio> #include <cmath> #include <algorithm> #include <iostream> #include <cstring> #include <queue> #include <set> #include <map> #include <stack> using namespace std; #define scd(a) scanf("%d",&a) #define scdd(a,b) scanf("%d%d",&a,&b) #define scddd(a,b,c) scanf("%d%d%d",&a,&b,&c) #define scl(a) scanf("%lld",&a) #define scll(a,b) scanf("%lld%lld",&a,&b) #define sclll(a,b,c) scanf("%lld%lld%lld",&a,&b,&c) #define prl(a) printf("%lld\n",a) #define prd(a) printf("%d\n",a) #define prf(a) printf("%lf\n",a) #define ptd(a) printf("%d ",a) #define scf(a) scanf("%lf",&a) #define scff(a,b) scanf("%lf%lf",&a,&b) #define scfff(a,b,c) scanf("%lf%lf%lf",&a,&b,&c) #define rint register int #define mem(a) memset(a,0,sizeof(a)) #define rush() int T;scd(T);while(T--) #define lc(i) (i<<1) #define rc(i) (i<<1|1) #define mp make_pair #define lowbit(x) (x&(-x)) #define For(i,st,en) for(int i=st;i<en;++i) #define SZ(x) ((int)(x).size()) #define ALL(x) (x).begin(), (x).end() template<typename S, typename T> inline bool Min(S &a, const T &b){ return a > b ? a = b, true : false; } template<typename S, typename T> inline bool Max(S &a, const T &b){ return a < b ? a = b, true : false; } typedef long long ll; typedef double db; inline int read() {char c=getchar();int x=0,f=1;while(c<'0'||c>'9') {if(c=='-')f=-1;c=getchar();}while(c>='0'&&c<='9') {x=x*10+c-'0';c=getchar();}return x*f;} const ll mod = 1e9 + 7; const int maxn = 1e5 + 10; int main () { stack<char> sta; string s; cin >> s; int len = s.length(); for (int i = 0; i < len; ++i) { if (sta.empty()) { sta.push(s[i]); continue; } if (s[i]==')') { if (sta.top()=='(') sta.pop(); else { puts("No"); return 0; } } if (s[i]==']') { if (sta.top()=='[') sta.pop(); else { puts("No"); return 0; } } if (s[i]=='}') { if (sta.top()=='{') sta.pop(); else { puts("No"); return 0; } } if (s[i]=='{'||s[i]=='('||s[i]=='[') sta.push(s[i]); } if (sta.empty()) puts("Yes"); else puts("No"); return 0; }
C子段乘积
逆元,再加上 子段里面如果有0的话整段的数字的乘积一定是0
#include <cstdio> #include <cmath> #include <algorithm> #include <iostream> #include <cstring> #include <queue> #include <set> #include <map> #include <stack> using namespace std; #define scd(a) scanf("%d",&a) #define scdd(a,b) scanf("%d%d",&a,&b) #define scddd(a,b,c) scanf("%d%d%d",&a,&b,&c) #define scl(a) scanf("%lld",&a) #define scll(a,b) scanf("%lld%lld",&a,&b) #define sclll(a,b,c) scanf("%lld%lld%lld",&a,&b,&c) #define prl(a) printf("%lld\n",a) #define prd(a) printf("%d\n",a) #define prf(a) printf("%lf\n",a) #define ptd(a) printf("%d ",a) #define scf(a) scanf("%lf",&a) #define scff(a,b) scanf("%lf%lf",&a,&b) #define scfff(a,b,c) scanf("%lf%lf%lf",&a,&b,&c) #define rint register int #define mem(a) memset(a,0,sizeof(a)) #define rush() int T;scd(T);while(T--) #define lc(i) (i<<1) #define rc(i) (i<<1|1) #define mp make_pair #define lowbit(x) (x&(-x)) #define For(i,st,en) for(int i=st;i<en;++i) #define SZ(x) ((int)(x).size()) #define ALL(x) (x).begin(), (x).end() template<typename S, typename T> inline bool Min(S &a, const T &b){ return a > b ? a = b, true : false; } template<typename S, typename T> inline bool Max(S &a, const T &b){ return a < b ? a = b, true : false; } typedef long long ll; typedef double db; inline int read() {char c=getchar();int x=0,f=1;while(c<'0'||c>'9') {if(c=='-')f=-1;c=getchar();}while(c>='0'&&c<='9') {x=x*10+c-'0';c=getchar();}return x*f;} const ll mod = 998244353; const int maxn = 2e5 + 10; ll dp[maxn]; ll a[maxn]; ll qpow(ll a, ll b) { ll res = 1; while (b) { if (b&1) { res = (res * a) % mod; } a = (a * a) % mod; b >>= 1; } return res; } int main () { int n = read(),m=read(); for (int i = 1; i <= n;++i) { scl(a[i]); } dp[m]=1; int cnt0 = 0; for (int i = 1; i <= m; ++i) { dp[m] = (dp[m] * a[i]) % mod; cnt0 += a[i]==0?1:0; } ll ans = dp[m]; for (int i = m+1; i <= n; ++i) { cnt0 += a[i]==0?1:0; cnt0 -= a[i-m]==0?1:0; if (cnt0 == 0 && dp[i-1]==0) { dp[i] = 1; for (int j = 0; j < m; j++) { dp[i] = (dp[i] * a[i-j]) % mod; } } else if (a[i]&&a[i-1]&&dp[i-1]) dp[i] = (a[i] * dp[i-1]%mod * qpow(a[i-m], mod-2))%mod; Max(ans, dp[i]); } prl(ans); return 0; }
D子段异或
前缀异或,如果pre[i] = x, 后面又有pre[j] = x, 那么(i+1,j)的异或值肯定是0。
#include <cstdio> #include <cmath> #include <algorithm> #include <iostream> #include <cstring> #include <queue> #include <set> #include <map> #include <stack> using namespace std; #define scd(a) scanf("%d",&a) #define scdd(a,b) scanf("%d%d",&a,&b) #define scddd(a,b,c) scanf("%d%d%d",&a,&b,&c) #define scl(a) scanf("%lld",&a) #define scll(a,b) scanf("%lld%lld",&a,&b) #define sclll(a,b,c) scanf("%lld%lld%lld",&a,&b,&c) #define prl(a) printf("%lld\n",a) #define prd(a) printf("%d\n",a) #define prf(a) printf("%lf\n",a) #define ptd(a) printf("%d ",a) #define scf(a) scanf("%lf",&a) #define scff(a,b) scanf("%lf%lf",&a,&b) #define scfff(a,b,c) scanf("%lf%lf%lf",&a,&b,&c) #define rint register int #define mem(a) memset(a,0,sizeof(a)) #define rush() int T;scd(T);while(T--) #define lc(i) (i<<1) #define rc(i) (i<<1|1) #define mp make_pair #define lowbit(x) (x&(-x)) #define For(i,st,en) for(int i=st;i<en;++i) #define SZ(x) ((int)(x).size()) #define ALL(x) (x).begin(), (x).end() template<typename S, typename T> inline bool Min(S &a, const T &b){ return a > b ? a = b, true : false; } template<typename S, typename T> inline bool Max(S &a, const T &b){ return a < b ? a = b, true : false; } typedef long long ll; typedef double db; inline int read() {char c=getchar();int x=0,f=1;while(c<'0'||c>'9') {if(c=='-')f=-1;c=getchar();}while(c>='0'&&c<='9') {x=x*10+c-'0';c=getchar();}return x*f;} const ll mod = 998244353; const int maxn = 2e5 + 10; ll pre[maxn]; ll post[maxn]; ll a[maxn]; int main () { int n = read(); ll ans = 0; map<ll,ll> cnt; for (int i = 1; i <= n; ++i) { scl(a[i]); pre[i] = pre[i-1]^a[i]; } cnt[0] = 1; for (int i = 1; i <= n; ++i) { if (cnt.count(pre[i]) == 0) { cnt[pre[i]] = 1; } else { ans+=cnt[pre[i]]; cnt[pre[i]]++; } } prl(ans); return 0; }
E最小表达式
只有+号,贪心+大数加法
#include <cstdio> #include <cmath> #include <algorithm> #include <iostream> #include <cstring> #include <queue> #include <set> #include <map> #include <stack> using namespace std; #define scd(a) scanf("%d",&a) #define scdd(a,b) scanf("%d%d",&a,&b) #define scddd(a,b,c) scanf("%d%d%d",&a,&b,&c) #define scl(a) scanf("%lld",&a) #define scll(a,b) scanf("%lld%lld",&a,&b) #define sclll(a,b,c) scanf("%lld%lld%lld",&a,&b,&c) #define prl(a) printf("%lld\n",a) #define prd(a) printf("%d\n",a) #define prf(a) printf("%lf\n",a) #define ptd(a) printf("%d ",a) #define scf(a) scanf("%lf",&a) #define scff(a,b) scanf("%lf%lf",&a,&b) #define scfff(a,b,c) scanf("%lf%lf%lf",&a,&b,&c) #define rint register int #define mem(a) memset(a,0,sizeof(a)) #define rush() int T;scd(T);while(T--) #define lc(i) (i<<1) #define rc(i) (i<<1|1) #define mp make_pair #define lowbit(x) (x&(-x)) #define For(i,st,en) for(int i=st;i<en;++i) #define SZ(x) ((int)(x).size()) #define ALL(x) (x).begin(), (x).end() template<typename S, typename T> inline bool Min(S &a, const T &b){ return a > b ? a = b, true : false; } template<typename S, typename T> inline bool Max(S &a, const T &b){ return a < b ? a = b, true : false; } typedef long long ll; typedef double db; inline int read() {char c=getchar();int x=0,f=1;while(c<'0'||c>'9') {if(c=='-')f=-1;c=getchar();}while(c>='0'&&c<='9') {x=x*10+c-'0';c=getchar();}return x*f;} const ll mod = 998244353; const int maxn = 5e5 + 10; char s[maxn]; int cnt[15]; vector<int> add(vector<int> &A, vector<int> &B) { if (A.size() < B.size()) return add(B, A); vector <int> C; int t = 0; for (int i = 0; i < A.size(); i ++ ) { t += A[i]; if (i < B.size()) t += B[i]; C.push_back(t % 10); t /= 10; } if (t) C.push_back(t); return C; } int main () { scanf("%s",s); int len = strlen(s); int c = 0; for (int i = 0; i < len; ++i) { if (s[i]!='+') cnt[s[i]-'0']++, c++; else cnt[11]++; } if (cnt[11] == 0) { sort(s,s+len); printf("%s\n",s); } else { vector<vector<int> > num; num.resize(cnt[11] + 1); int i = 1; int j = 0; while (c) { while (cnt[i]==0)++i; num[j].push_back(i); cnt[i]--; j = (j + 1) % (cnt[11] + 1); c--; } for (int k = 0; k <= cnt[11]; ++k) { reverse(ALL(num[k])); } vector<int> C = add(num[0], num[1]); for (int k = 2; k <= cnt[11]; ++k) C = add(num[k], C); for (int kk = C.size() - 1; kk >= 0; kk -- ) cout << C[kk]; cout << endl; } return 0; }
F树上博弈
通过规则是可以知道先手后手之间的距离为偶数,先手必胜满足题意。
题解好像是统计了深度奇偶的数量,再利用握手定理解掉了
考场上还是没转过这个弯来,dp[j][0]统计了以j为根节点的深度为偶数结点的数量,
每一次dfs完一棵子树,相同奇偶性的的结点肯定要统计进来。
#include <cstdio> #include <cmath> #include <algorithm> #include <iostream> #include <cstring> #include <queue> #include <set> #include <map> #include <stack> using namespace std; #define scd(a) scanf("%d",&a) #define scdd(a,b) scanf("%d%d",&a,&b) #define scddd(a,b,c) scanf("%d%d%d",&a,&b,&c) #define scl(a) scanf("%lld",&a) #define scll(a,b) scanf("%lld%lld",&a,&b) #define sclll(a,b,c) scanf("%lld%lld%lld",&a,&b,&c) #define prl(a) printf("%lld\n",a) #define prd(a) printf("%d\n",a) #define prf(a) printf("%lf\n",a) #define ptd(a) printf("%d ",a) #define scf(a) scanf("%lf",&a) #define scff(a,b) scanf("%lf%lf",&a,&b) #define scfff(a,b,c) scanf("%lf%lf%lf",&a,&b,&c) #define rint register int #define mem(a) memset(a,0,sizeof(a)) #define rush() int T;scd(T);while(T--) #define lc(i) (i<<1) #define rc(i) (i<<1|1) #define mp make_pair #define lowbit(x) (x&(-x)) #define For(i,st,en) for(int i=st;i<en;++i) #define SZ(x) ((int)(x).size()) #define ALL(x) (x).begin(), (x).end() template<typename S, typename T> inline bool Min(S &a, const T &b){ return a > b ? a = b, true : false; } template<typename S, typename T> inline bool Max(S &a, const T &b){ return a < b ? a = b, true : false; } typedef long long ll; typedef double db; inline int read() {char c=getchar();int x=0,f=1;while(c<'0'||c>'9') {if(c=='-')f=-1;c=getchar();}while(c>='0'&&c<='9') {x=x*10+c-'0';c=getchar();}return x*f;} const ll mod = 998244353; const int maxn = 1e6 + 10; struct node { int v, nxt; }edge[2 * maxn]; int head[maxn],tot; int h[maxn]; ll dp[maxn][2]; void add(int u,int v){ edge[++tot].v = v; edge[tot].nxt = head[u]; head[u] = tot; } ll ans = 0; void dfs(int u,int f) { h[u] = h[f] + 1; if (h[u]&1) { dp[u][1]++; } else dp[u][0]++; for (int i = head[u];i;i = edge[i].nxt) { int v = edge[i].v; if (v==f) continue; dfs(v, u); ans += dp[v][0] * dp[u][0]; ans += dp[v][1] * dp[u][1]; dp[u][0] += dp[v][0]; dp[u][1] += dp[v][1]; } } int main () { int n = read(); for (int i = 2; i <= n; ++i) { int f = read(); add(i,f); add(f,i); } dfs(1,0); prl(ans*2); return 0; }
G音乐鉴赏
概率学得还行吧。。。
#include <cstdio> #include <cmath> #include <algorithm> #include <iostream> #include <cstring> #include <queue> #include <set> #include <map> #include <stack> using namespace std; #define scd(a) scanf("%d",&a) #define scdd(a,b) scanf("%d%d",&a,&b) #define scddd(a,b,c) scanf("%d%d%d",&a,&b,&c) #define scl(a) scanf("%lld",&a) #define scll(a,b) scanf("%lld%lld",&a,&b) #define sclll(a,b,c) scanf("%lld%lld%lld",&a,&b,&c) #define prl(a) printf("%lld\n",a) #define prd(a) printf("%d\n",a) #define prf(a) printf("%lf\n",a) #define ptd(a) printf("%d ",a) #define scf(a) scanf("%lf",&a) #define scff(a,b) scanf("%lf%lf",&a,&b) #define scfff(a,b,c) scanf("%lf%lf%lf",&a,&b,&c) #define rint register int #define mem(a) memset(a,0,sizeof(a)) #define rush() int T;scd(T);while(T--) #define lc(i) (i<<1) #define rc(i) (i<<1|1) #define mp make_pair #define lowbit(x) (x&(-x)) #define For(i,st,en) for(int i=st;i<en;++i) #define SZ(x) ((int)(x).size()) #define ALL(x) (x).begin(), (x).end() template<typename S, typename T> inline bool Min(S &a, const T &b){ return a > b ? a = b, true : false; } template<typename S, typename T> inline bool Max(S &a, const T &b){ return a < b ? a = b, true : false; } typedef long long ll; typedef double db; const db eps = 1e-6; inline int read() {char c=getchar();int x=0,f=1;while(c<'0'||c>'9') {if(c=='-')f=-1;c=getchar();}while(c>='0'&&c<='9') {x=x*10+c-'0';c=getchar();}return x*f;} const ll mod = 998244353; const int maxn = 1e5 + 10; int n; db s[maxn]; db check(db p) { db sum = 0; for (int i = 1; i <= n; ++i) { sum += (1.0-(90.0 - s[i] * (1.0-p)) / (90.0 * p)); } return sum / (1.0*n); } int main () { n = read(); for (int i = 1; i <= n; ++i) { scf(s[i]); } db l = 0, r = 1, mid = 0; while (r-l>=eps){ mid = (l+r)/2; db res = check(mid); if (res < 0.1){ r = mid; } else if (res > 0.1){ l = mid; }; } printf("%.2lf%%\n", mid*100); return 0; }
H坐火车
线段树得姿势端正一些才可以。
可以通过前缀后缀数组动态地来统计某种颜色的数量,而且不同颜色之间的贡献是独立的。
从左到右遍历,对于当前的车厢,对答案的贡献要剪掉当前车厢与前面车厢相同颜色的对数。
增加的贡献是当前颜色作为前面的车厢对后面有相同颜色车厢的贡献。
#include <cstdio> #include <cmath> #include <algorithm> #include <iostream> #include <cstring> #include <queue> #include <set> #include <map> #include <stack> using namespace std; #define scd(a) scanf("%d",&a) #define scdd(a,b) scanf("%d%d",&a,&b) #define scddd(a,b,c) scanf("%d%d%d",&a,&b,&c) #define scl(a) scanf("%lld",&a) #define scll(a,b) scanf("%lld%lld",&a,&b) #define sclll(a,b,c) scanf("%lld%lld%lld",&a,&b,&c) #define prl(a) printf("%lld\n",a) #define prd(a) printf("%d\n",a) #define prf(a) printf("%lf\n",a) #define ptd(a) printf("%d ",a) #define scf(a) scanf("%lf",&a) #define scff(a,b) scanf("%lf%lf",&a,&b) #define scfff(a,b,c) scanf("%lf%lf%lf",&a,&b,&c) #define rint register int #define mem(a) memset(a,0,sizeof(a)) #define rush() int T;scd(T);while(T--) #define lc(i) (i<<1) #define rc(i) (i<<1|1) #define mp make_pair #define lowbit(x) (x&(-x)) #define For(i,st,en) for(int i=st;i<en;++i) #define SZ(x) ((int)(x).size()) #define ALL(x) (x).begin(), (x).end() template<typename S, typename T> inline bool Min(S &a, const T &b){ return a > b ? a = b, true : false; } template<typename S, typename T> inline bool Max(S &a, const T &b){ return a < b ? a = b, true : false; } typedef long long ll; typedef double db; const db eps = 1e-6; inline int read() {char c=getchar();int x=0,f=1;while(c<'0'||c>'9') {if(c=='-')f=-1;c=getchar();}while(c>='0'&&c<='9') {x=x*10+c-'0';c=getchar();}return x*f;} const int maxn = 5e5 + 10; int n, m; int col[maxn], l[maxn],r[maxn]; int pre[maxn], post[maxn]; ll sum[maxn<<2]; inline void update(int i, int l, int r, int p, int v) { sum[i]+=v; if (l==r) { return; } int mid = (l + r)>>1; if (p <= mid) update(lc(i), l, mid, p, v); else update(rc(i), mid+1, r, p, v); // sum[i] = sum[lc(i)] + sum[rc(i)]; } inline ll query(int i, int l, int r, int L, int R) { if (L <= l && r <= R) { return sum[i]; } int mid = (l + r) >> 1; ll res = 0; if (L <= mid) { res += query(lc(i), l, mid, L, R); } if (R > mid) { res += query(rc(i), mid+1, r, L, R); } return res; } int main () { n = read(); for (int i = 1; i <= n; ++i) { col[i] = read(),l[i] = read(), r[i] = read(); post[col[i]]++; } for (int i = 1; i <= n; ++i) { update(1, 1, 500000, col[i], -pre[col[i]]); post[col[i]]--; update(1, 1, 500000, col[i-1], post[col[i-1]]); pre[col[i-1]]++; printf("%lld ", query(1, 1, 500000, l[i],r[i])); }puts(""); return 0; }
I匹配星星
#include <stdio.h> #include <string.h> #include <math.h> #include <set> #include <algorithm> const int maxn = 100000 + 10; typedef long long ll; using namespace std; struct node { int x,y,z; bool operator < (const node &r) const { if (x == r.x) return z < r.z; return x > r.x; } } s[maxn]; int main() { int n; scanf("%d",&n); for(int i = 1; i <= n; i++) scanf("%d %d %d", &s[i].x, &s[i].y, &s[i].z); sort(s+1, s+1+n); int ans = 0; set<int> se; for(int i = 1; i <= n; i++) { if(s[i].z == 1){ se.insert(s[i].y); } else { auto it = se.upper_bound(s[i].y); if ( it != se.end()) { se.erase(it); ans++; } } } printf("%d\n", ans); return 0; }