两个队友链接:
A. PERFECT NUMBER PROBLEM
#include<bits/stdc++.h> using namespace std; int main() { cout<<"6 28 496 8128 33550336 "; return 0; }
B. Greedy HOUHOU
C. Angry FFF Party
思路:java大数算,贪心减
代码:
import java.util.*; import java.math.*; public class Main { /** * @param args */ static class Matrix { BigInteger a[][] = new BigInteger [2][2]; public void init() { for (int i = 0; i < 2; ++i) for (int j = 0; j < 2; ++j) a[i][j] = BigInteger.ZERO; } public void _init() { init(); for (int i = 0; i < 2; ++i) a[i][i] = BigInteger.ONE; } public static Matrix mul(Matrix A, Matrix B) { Matrix res = new Matrix(); res.init(); for (int i = 0; i < 2; ++i) { for (int j = 0; j < 2; ++j) { for (int k = 0; k < 2; ++k) { res.a[i][k] = res.a[i][k].add(A.a[i][j].multiply(B.a[j][k])); } } } return res; } public static Matrix q_pow(Matrix A, BigInteger k) { Matrix res = new Matrix(); res._init(); while(k.compareTo(BigInteger.ZERO) > 0) { if(k.mod(BigInteger.valueOf(2)).compareTo(BigInteger.ZERO) > 0) res = mul(res, A); A = mul(A, A); k = k.shiftRight(1); } return res; } public static BigInteger get_fib(BigInteger n) { if(n.compareTo(BigInteger.ONE) == 0) return BigInteger.ONE; if(n.compareTo(BigInteger.valueOf(2)) == 0) return BigInteger.ONE; Matrix A = new Matrix(); A.a[1][1] = BigInteger.ZERO; A.a[0][0] = A.a[1][0] = A.a[0][1] = BigInteger.ONE; A = q_pow(A, n.subtract(BigInteger.valueOf(2))); return A.a[0][0].add(A.a[0][1]); } } public static BigInteger f[] = new BigInteger[100]; public static int ans[] = new int[100]; public static void main(String[] args) { // TODO Auto-generated method stub Scanner in = new Scanner(System.in); int T = in.nextInt(); for (int i = 1; i <= 28; ++i) { f[i] = Matrix.get_fib(Matrix.get_fib(BigInteger.valueOf(i))); } while(T > 0) { --T; BigInteger W = in.nextBigInteger(); int cnt = 0; for (int i = 28; i >= 6; --i) { if(f[i].compareTo(W) <= 0) { ans[++cnt] = i; W = W.subtract(f[i]); } } if(W.compareTo(BigInteger.valueOf(1)) == 0) { ans[++cnt] = 1; } else if(W.compareTo(BigInteger.valueOf(2)) == 0){ ans[++cnt] = 2; ans[++cnt] = 1; } else if(W.compareTo(BigInteger.valueOf(3)) == 0) { ans[++cnt] = 3; ans[++cnt] = 2; ans[++cnt] = 1; } else if(W.compareTo(BigInteger.valueOf(4)) == 0) { ans[++cnt] = 4; ans[++cnt] = 2; ans[++cnt] = 1; } else if(W.compareTo(BigInteger.valueOf(5)) == 0) { ans[++cnt] = 4; ans[++cnt] = 3; ans[++cnt] = 2; ans[++cnt] = 1; } else if(W.compareTo(BigInteger.valueOf(6)) == 0) { ans[++cnt] = 5; ans[++cnt] = 1; } else if(W.compareTo(BigInteger.valueOf(7)) == 0) { ans[++cnt] = 5; ans[++cnt] = 2; ans[++cnt] = 1; } else if(W.compareTo(BigInteger.valueOf(8)) == 0) { ans[++cnt] = 5; ans[++cnt] = 3; ans[++cnt] = 2; ans[++cnt] = 1; } else if(W.compareTo(BigInteger.valueOf(9)) == 0) { ans[++cnt] = 5; ans[++cnt] = 4; ans[++cnt] = 2; ans[++cnt] = 1; } else if(W.compareTo(BigInteger.valueOf(10)) == 0) { ans[++cnt] = 5; ans[++cnt] = 4; ans[++cnt] = 3; ans[++cnt] = 2; ans[++cnt] = 1; } else if(W.compareTo(BigInteger.valueOf(0)) != 0){ System.out.println(-1); continue; } for (int i = cnt; i >= 1; --i) { System.out.print(ans[i]); if(i == 1)System.out.println(""); else System.out.print(" "); } } } }
D. Match Stick Game
思路:mx[i][j]:用i根火柴组成一个位数为j的数这个数的最大值 mn[i][j]:用i根火柴组成一个位数为j的数这个数的最小值
dp[i][j]:处理到第i位用了j根火柴式子的最大值
代码:
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/stdc++.h> using namespace std; #define y1 y11 #define fi first #define se second #define pi acos(-1.0) #define LL long long #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r //#define mp make_pair #define pb push_back #define ULL unsigned LL #define pll pair<LL, LL> #define pli pair<LL, int> #define pii pair<int, int> #define piii pair<pii, int> #define pdi pair<double, int> #define pdd pair<double, double> #define mem(a, b) memset(a, b, sizeof(a)) #define debug(x) cerr << #x << " = " << x << " "; #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); //head const int N = 105, M = 70; char s[N]; int a[N]; int n, T; int mx[M][10], mn[M][10]; map<char, int>mp; int t[10] = {-1, -1, 1, 7, 4, 5, 9, 8}; LL dp[N][705]; void init() { for (int i = 1; i < M; ++i) { for (int j = 0; j <= 9; ++j) mx[i][j] = INT_MIN, mn[i][j] = INT_MAX; } mx[0][0] = mn[0][0] = 0; for (int i = 1; i <= M; ++i) { for (int j = 1; j <= 9; ++j) { for (int k = 2; k <= 7 && k <= i; ++k) { if(mx[i-k][j-1] != INT_MIN) mx[i][j] = max(mx[i-k][j-1]*10+t[k], mx[i][j]); if(mn[i-k][j-1] != INT_MAX) mn[i][j] = min(mn[i-k][j-1]*10+t[k], mn[i][j]); } } } } int main() { mp['0']=6; mp['1']=2; mp['2']=5; mp['3']=5; mp['4']=4; mp['5']=5; mp['6']=6; mp['7']=3; mp['8']=7; mp['9']=6; mp['+']=2; mp['-']=1; init(); scanf("%d", &T); while(T--) { scanf("%d", &n); scanf("%s", s); int c1 = 1, cnt = 0; for (int i = 0; i < n; ++i) { if(isdigit(s[i])) cnt += mp[s[i]], a[c1]++; else cnt += mp[s[i]], ++c1; } n = c1; for (int i = 0; i <= n; ++i) for (int j = 0; j < 705; ++j) dp[i][j] = LONG_MIN; dp[0][0] = 0; for (int i = 1; i <= n; ++i) { if(i == 1) { for (int j = 1; j <= cnt; ++j) { for (int k = 1; k < M && k <= j; ++k) { if(dp[i-1][j-k] != LONG_MIN && mx[k][a[i]] != INT_MIN) dp[i][j] = max(dp[i-1][j-k] + mx[k][a[i]], dp[i][j]); } } } else { for (int j = 1; j <= cnt; ++j) { for (int k = 1; k < M; ++k) { if(k+2 <= j && dp[i-1][j-k-2] != LONG_MIN && mx[k][a[i]] != INT_MIN) dp[i][j] = max(dp[i-1][j-k-2] + mx[k][a[i]], dp[i][j]); if(k+1 <= j && dp[i-1][j-k-1] != LONG_MIN && mn[k][a[i]] != INT_MAX) dp[i][j] = max(dp[i-1][j-k-1] - mn[k][a[i]], dp[i][j]); } } } } printf("%lld ", dp[n][cnt]); for (int i = 1; i <= n; ++i) a[i] = 0; } return 0; }
E. Card Game
F. Information Transmitting
G. tsy's number
H. Coloring Game
思路:4*3^(n-2)
代码:
#include<bits/stdc++.h> #define ll long long using namespace std; const int mod=1e9+7; ll quick(ll x,ll n) { ll ans=1; while(n) { if(n%2==0) { x=x*x%mod; n=n/2; } else {ans=ans*x%mod; n--; } } return ans; } int main() { ll n; cin>>n; if(n==1) { cout<<1<<endl; } else { cout<<(quick(2,2)%mod*quick(3,n-2)%mod+mod)%mod<<endl; } return 0; }
I. Max answer
思路:单调栈+区间RMQ
代码:
#include <bits/stdc++.h> using namespace std; #define LL long long #define fi first #define se second #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r const int N = 5e5 + 5; int a[N], pre[N], suf[N]; LL sum[N], mx[N<<2], mn[N<<2]; stack<int> st; int n; void push_up(int rt) { mn[rt] = min(mn[rt<<1], mn[rt<<1|1]); mx[rt] = max(mx[rt<<1], mx[rt<<1|1]); } void build(int rt, int l, int r) { if(l == r) { mx[rt] = mn[rt] = sum[l]; return ; } int m = l+r >> 1; build(ls); build(rs); push_up(rt); } LL querymx(int L, int R, int rt, int l, int r) { if(L <= l && r <= R) return mx[rt]; int m = l+r >> 1; LL ans = LONG_MIN; if(L <= m) ans = max(ans, querymx(L, R, ls)); if(R > m) ans = max(ans, querymx(L, R, rs)); return ans; } LL querymn(int L, int R, int rt, int l, int r) { if(L <= l && r <= R) return mn[rt]; int m = l+r >> 1; LL ans = LONG_MAX; if(L <= m) ans = min(ans, querymn(L, R, ls)); if(R > m) ans = min(ans, querymn(L, R, rs)); return ans; } int main() { scanf("%d", &n); for (int i = 1; i <= n; ++i) scanf("%d", &a[i]); for (int i = 1; i <= n; ++i) sum[i] = sum[i-1] + a[i]; build(1, 0, n); a[0] = a[n+1] = INT_MIN; st.push(0); for (int i = 1; i <= n; ++i) { while(!st.empty() && a[st.top()] >= a[i]) st.pop(); pre[i] = st.top(); st.push(i); } while(!st.empty()) st.pop(); st.push(n+1); for (int i = n; i >= 1; --i) { while(!st.empty() && a[st.top()] >= a[i]) st.pop(); suf[i] = st.top(); st.push(i); } LL ans = 0; for (int i = 1; i <= n; ++i) { int l = pre[i], r = i-1; int ll = i, rr = suf[i]-1; if(a[i] < 0) { ans = max(ans, a[i]*(querymn(ll, rr, 1, 0, n)-querymx(l, r, 1, 0, n))); } else if(a[i] > 0) { ans = max(ans, a[i]*(querymx(ll, rr, 1, 0, n)-querymn(l, r, 1, 0, n))); } } printf("%lld ", ans); return 0; }
J. Distance on the tree
思路:离线+树剖
代码:
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/stdc++.h> using namespace std; #define y1 y11 #define fi first #define se second #define pi acos(-1.0) #define LL long long #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r //#define mp make_pair #define pb push_back #define ULL unsigned LL #define pll pair<LL, LL> #define pli pair<LL, int> #define pii pair<int, int> #define piii pair<pii, int> #define pdi pair<double, int> #define pdd pair<double, double> #define mem(a, b) memset(a, b, sizeof(a)) #define debug(x) cerr << #x << " = " << x << " "; #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); //head const int N = 1e5 + 5; vector<int> g[N]; int fa[N], dp[N], sz[N], son[N], top[N], dfn[N], to[N], cnt = 0, n, m; int tree[N<<2], ans[N]; struct edge { int u, v, w; int id; bool operator < (const edge & rhs) const { return w < rhs.w; } }e[N], q[N]; void push_up(int rt) { tree[rt] = tree[rt<<1] + tree[rt<<1|1]; } void update(int p, int x, int rt, int l, int r) { if(l == r) { tree[rt] += x; return ; } int m = l+r >> 1; if(p <= m) update(p, x, ls); else update(p, x, rs); push_up(rt); } int query(int L, int R, int rt, int l, int r) { if(L <= l && r <= R) return tree[rt]; int m = l+r >> 1; int ans = 0; if(L <= m) ans += query(L, R, ls); if(R > m) ans += query(L, R, rs); return ans; } void dfs1(int u, int o) { fa[u] = o; sz[u] = 1; dp[u] = dp[o] + 1; for (int i = 0; i < g[u].size(); ++i) { int v = g[u][i]; if(v != o) { dfs1(v, u); sz[u] += sz[v]; if(sz[v] > sz[son[u]]) son[u] = v; } } } void dfs2(int u, int t) { top[u] = t; dfn[u] = ++cnt; to[cnt] = u; if(!son[u]) return ; dfs2(son[u], t); for (int i = 0; i < g[u].size(); ++i) { int v = g[u][i]; if(v != fa[u] && v != son[u]) dfs2(v, v); } } int sum(int u, int v) { int ans = 0, fu = top[u], fv = top[v]; while(fu != fv) { if(dp[fu] >= dp[fv]) ans += query(dfn[fu], dfn[u], 1, 1, n), u = fa[fu], fu = top[u]; else ans += query(dfn[fv], dfn[v], 1, 1, n), v = fa[fv], fv = top[v]; } if(dfn[u] < dfn[v]) ans += query(dfn[u]+1, dfn[v], 1, 1, n); else if(dfn[v] < dfn[u]) ans += query(dfn[v]+1, dfn[u], 1, 1, n); return ans; } int main() { scanf("%d %d", &n, &m); for (int i = 1; i < n; ++i) { scanf("%d %d %d", &e[i].u, &e[i].v, &e[i].w); g[e[i].u].pb(e[i].v); g[e[i].v].pb(e[i].u); } dfs1(1, 1); dfs2(1, 1); for (int i = 1; i <= m; ++i) scanf("%d %d %d", &q[i].u, &q[i].v, &q[i].w), q[i].id = i; sort(e+1, e+n); sort(q+1, q+1+m); int now = 1; for (int i = 1; i <= m; ++i) { while(now < n && e[now].w <= q[i].w) { int u = e[now].u, v = e[now].v; if(dp[u] < dp[v]) swap(u, v); update(dfn[u], 1, 1, 1, n); ++now; } ans[q[i].id] = sum(q[i].u, q[i].v); } for (int i = 1; i <= m; ++i) printf("%d ", ans[i]); return 0; }
K. MORE XOR
#include<bits/stdc++.h> #define ll long long using namespace std; const int mod=1e9+7; const int maxn=1e5+10; int a[maxn]; int n; int a1000[maxn]; int a0100[maxn]; int a0010[maxn]; int a0001[maxn]; void make1() { for(int i=1;i<=n;i++) { if(i%4==1) a1000[i]=a1000[i-1]^a[i]; else a1000[i]=a1000[i-1]; } for(int i=1;i<=n;i++) { if(i%4==2) a0100[i]=a0100[i-1]^a[i]; else a0100[i]=a0100[i-1]; } for(int i=1;i<=n;i++) { if(i%4==3) a0010[i]=a0010[i-1]^a[i]; else a0010[i]=a0010[i-1]; } for(int i=1;i<=n;i++) { if(i%4==0) a0001[i]=a0001[i-1]^a[i]; else a0001[i]=a0001[i-1]; } } int work(int l,int r) { int d=r-l+1; int ans1=0; int ans2=0; if(l%4==1) ans1^=a1000[r]^a1000[l-1]; else if(l%4==2) ans1^=a0100[r]^a0100[l-1]; else if(l%4==3) ans1^=a0010[r]^a0010[l-1]; else ans1^=a0001[r]^a0001[l-1]; if(l%4==1) ans2^=a0100[r]^a0100[l-1]; else if(l%4==2) ans2^=a0010[r]^a0010[l-1]; else if(l%4==3) ans2^=a0001[r]^a0001[l-1]; else ans2^=a1000[r]^a1000[l-1]; if(d%4==0) return 0; else if(d%4==1) return ans1; else if(d%4==2) return ans1^ans2; else return ans2; } int main() { int T; scanf("%d",&T); while(T--) { scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&a[i]); make1(); int q; scanf("%d",&q); while(q--) { int l,r; scanf("%d %d",&l,&r); printf("%d ",work(l,r)); } for(int i=1;i<=n;i++) { a0001[i]=0; a1000[i]=0;a0010[i]=0;a0100[i]=0; } } return 0; }
L. qiqi'tree
思路:暴力计算几何
代码:
#include<bits/stdc++.h> const double PI=acos(-1.0); const double TT=PI/3; using namespace std; struct Point { double x,y; Point(){} Point(double x, double y) :x(x), y(y){} };; struct Segment{ Point a,b; Segment(Point x,Point y ) { a=x;b=y; }; Segment(){}; };; struct Line { Point a,b; Line(Point x,Point y ) { a=x;b=y; }; Line(){}; };; typedef Point Point; Point operator + (Point A, Point B){ return Point(A.x+B.x, A.y+B.y); } // 向量相加 Point operator - (Point A, Point B){ return Point(B.x-A.x, B.y-A.y); } // 向量生成 A-B; double operator * (Point A, Point B){ return A.x*B.x-A.y*B.y; } // 点积 double operator ^ (Point A, Point B){ return A.x*B.y-A.y*B.x; } // 叉积 double Dot(Point A, Point B) { return A.x*B.x + A.y*B.y; } // 点积 double Cross(Point A, Point B) { return A.x*B.y-A.y*B.x; } // 叉积 double Length(Point A) { return sqrt(Dot(A, A)); } // 向量长度 double dis(Point a,Point b) { return sqrt( (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y) ); } Line qq; bool check(Segment A,Line B) { Point a=A.a; Point b=A.b; Point c=B.a; Point d=B.b; if(Cross(a-c,a-d)*Cross(b-c,b-d)>0 ) return 1; else return 0; return 0; } Point make(Segment A,Line B) { Point a=A.a; Point b=A.b;Point c=B.a; Point d=B.b; double A1=b.y-a.y,B1=-(b.x-a.x),C1=b.y*a.x-b.x*a.y; double A2=d.y-c.y,B2=-(d.x-c.x),C2=d.y*c.x-d.x*c.y; double k=A1*B2-A2*B1; double x=-(B1*C2-C1*B2)*1.000000000/k; double y=(A1*C2-C1*A2)*1.00000000/k; Point kk; kk.x=x; kk.y=y; return kk; } double dfs(double l,int k,int d,Point x,double ff) { if(k==d) return 0; double ans=0; Segment x1; x1.a=x; x1.b.x=x.x+l*sin(ff); x1.b.y=x.y+l*cos(ff); Point W; W.x=x.x+l*sin(ff); W.y=x.y+l*cos(ff); if(check(x1,qq)==1) { ans+=l; ans+=dfs(l/4,k+1,d,W,ff-TT); ans+=dfs(l/4,k+1,d,W,ff); ans+=dfs(l/4,k+1,d,W,ff+TT); } else { Point P=make(x1,qq); ans+=dis(x,P); } return ans; } void work(double l,int d) { Segment x1; x1.a.x=0; x1.a.y=0; x1.b.x=0; x1.b.y=l; double ans=0; Point W; W.x=0; W.y=l; if(check(x1,qq)==1) { ans+=l; ans+=dfs(l/4,1,d,W,-TT); ans+=dfs(l/4,1,d,W,0); ans+=dfs(l/4,1,d,W,TT); } else { Point x; x.x=0; x.y=0; Point P=make(x1,qq); ans+=dis(x,P); } cout<<ans<<endl; } int main() { cout<<fixed<<setprecision(6); int T; cin>>T; while(T--) { int d; double l,x1,y1,k; cin>>l>>d>>x1>>y1>>k; qq.a.x=x1; qq.a.y=y1; qq.b.x=x1+1; qq.b.y=y1+k*1; work(l,d); } }
M. Subsequence
#include <bits/stdc++.h> using namespace std; #define fi first #define se second #define pb push_back const int inf = 0x3f3f3f3f; char str[100009],s1[100009]; int cnt1[300],cc[300]; int nxt[100009][30]; int pt[30]; int getid(char c) { return c - 'a' + 1; } int main(){ scanf("%s", str); int len = strlen(str); for(int i=0; i<30; i++) pt[i] = len + 1; for(int i=0; i<30; i++) nxt[len+1][i] = len+1; for(int i=len-1; i>=0; i--) { for(int j=0; j<30; j++) nxt[i][j] = pt[j]; pt[getid(str[i])] = i; } int T; scanf("%d", &T); while(T--) { scanf("%s", s1); int l = strlen(s1); int flag = 1,id = pt[getid(s1[0])]; for(int i=1; i<l; i++) { int d = nxt[id][getid(s1[i])]; if(d > id) { id = d; } else { flag = 0; break; } } if(flag && id <= len) puts("YES"); else puts("NO"); } return 0; }