A.t == 10的时候输出1后面跟n - 1个0,否则输出n个t
#include <map> #include <set> #include <ctime> #include <cmath> #include <queue> #include <stack> #include <vector> #include <string> #include <bitset> #include <cstdio> #include <cstdlib> #include <cstring> #include <sstream> #include <iostream> #include <algorithm> #include <functional> using namespace std; #define For(i,x,y) for(int i=x;i<=y;i++) #define _For(i,y) for(int i=x;i>=y;i--) #define Mem(f,x) memset(f,sizeof(f)) #define Sca(x) scanf("%d",&x) #define Sca2(x,y) scanf("%d%d",&x,&y) #define Sca3(x,y,z) scanf("%d%d%d",&y,&z) #define Scl(x) scanf("%lld",&x) #define Pri(x) printf("%d\n",x) #define Prl(x) printf("%lld\n",x) #define CLR(u) for(int i=0;i<=N;i++)u[i].clear(); #define LL long long #define ULL unsigned long long #define mp make_pair #define PII pair<int,int> #define PIL pair<int,long long> #define PLL pair<long long,long long> #define pb push_back #define fi first #define se second typedef vector<int> VI; int read(){int x = 0,f = 1;char c = getchar();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 double eps = 1e-9; const int maxn = 110; const int INF = 0x3f3f3f3f; const int mod = 1e9 + 7; int N,M,K; int main(){ Sca2(N,M); if(M == 10){ if(N == 1) puts("-1"); else{ printf("1"); for(int i = 0 ; i < N - 1; i ++) printf("0"); } return 0; } for(int i = 1; i <= N; i ++) printf("%d",M); return 0; }
B.枚举每一个二进制中只含一个0的数字,符合给出范围的就计入贡献。
#include <map> #include <set> #include <ctime> #include <cmath> #include <queue> #include <stack> #include <vector> #include <string> #include <bitset> #include <cstdio> #include <cstdlib> #include <cstring> #include <sstream> #include <iostream> #include <algorithm> #include <functional> using namespace std; #define For(i,K; string t; bitset<70>Q[70]; int main(){ ULL l,r;cin >> l >> r; LL ans = 0; for(int i = 0 ; i < 63; i ++){ for(int j = 0; j < i; j ++){ Q[i][j] = 1; } for(int j = 0 ; j < i - 1; j ++){ Q[i][j] = 0; ULL sum = Q[i].to_ullong(); if(l <= sum && sum <= r){ ans++; } Q[i][j] = 1; } } Prl(ans); return 0; }
C.每个点只能向右扩展或者向下扩展,分别维护出向右向下扩展的二位前缀和。
计算的时候调整边界,容斥出答案为dp[x2][y2] - dp[x2][y1 - 1] - dp[x1 - 1][y2] + dp[x1 - 1][y1 - 1]
#include <map> #include <set> #include <ctime> #include <cmath> #include <queue> #include <stack> #include <vector> #include <string> #include <bitset> #include <cstdio> #include <cstdlib> #include <cstring> #include <sstream> #include <iostream> #include <algorithm> #include <functional> using namespace std; #define For(i,f = 1;char c = getchar();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 double eps = 1e-9; const int maxn = 510; const int INF = 0x3f3f3f3f; const int mod = 1e9 + 7; int N,K; char MAP[maxn][maxn]; LL dp[2][maxn][maxn]; int main(){ Sca2(N,M); for(int i = 1; i <= N ; i ++) scanf("%s",MAP[i] + 1); for(int i = 1; i <= N ; i ++){ for(int j = 1; j <= M; j ++){ if(MAP[i][j] == ‘#‘) continue; if(i != N && MAP[i + 1][j] == ‘.‘) dp[0][i][j]++; if(j != M && MAP[i][j + 1] == ‘.‘) dp[1][i][j]++; } } for(int i = 1; i <= N ; i ++){ for(int j = 1; j <= M ; j ++){ dp[1][i][j] = dp[1][i][j] + dp[1][i - 1][j] + dp[1][i][j - 1] - dp[1][i - 1][j - 1]; dp[0][i][j] = dp[0][i][j] + dp[0][i - 1][j] + dp[0][i][j - 1] - dp[0][i - 1][j - 1]; } } int Q; Sca(Q); while(Q--){ int x1,x2,y1,y2; Sca2(x1,y1); Sca2(x2,y2); x2--; LL ans = dp[0][x2][y2] - dp[0][x1 - 1][y2] - dp[0][x2][y1 - 1] + dp[0][x1 - 1][y1 - 1]; x2++; y2--; ans += dp[1][x2][y2] - dp[1][x1 - 1][y2] - dp[1][x2][y1 - 1] + dp[1][x1 - 1][y1 - 1]; Prl(ans); } return 0; }
D.dp[i][j]表示以i到j这段区间内结尾的数字的种数。
然后可以写出一个n ^ 4的dp(三层枚举一层比较),用EXKMP预处理出每两个位置之间的最长公共前缀优化掉一层比较。
用树状数组代替dp优化掉一层枚举,时间复杂度n2lognlogn
补:赛后十分钟过题真刺激,因为开始贪图简便写了个BFS来dp,就不好优化了,以后能直接写的dp还是直接写
#include <map> #include <set> #include <ctime> #include <cmath> #include <queue> #include <stack> #include <vector> #include <string> #include <bitset> #include <cstdio> #include <cstdlib> #include <cstring> #include <sstream> #include <iostream> #include <algorithm> #include <functional> using namespace std; #define For(i,f = 1;char c = getchar();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 double eps = 1e-9; const int maxn = 5010; const int INF = 0x3f3f3f3f; const int mod = 1e9 + 7; int N,K; char str[maxn]; LL dp[maxn][maxn]; void pre_EKMP(char x[],int m,int next[]){ next[0] = m; int j = 0; while(j + 1 < m && x[j] == x[j + 1]) j ++; next[1] = j; int k = 1; for(int i = 2; i < m ; i ++){ int p = next[k] + k - 1; int L = next[i - k]; if(i + L < p + 1) next[i] = L; else{ j = max(0,p - i + 1); while(i + j < m && x[i + j] == x[j]) j ++; next[i] = j; k = i; } } } int nxt[maxn][maxn]; bool cmp(int l1,int r1,int l2,int r2){ int len1 = r1 - l1 + 1,len2 = r2 - l2 + 1; if(len1 > len2) return 1; if(len1 < len2) return 0; int l = nxt[l2][l1]; if(l >= len1) return 0; // cout << l1 << " " << l2 << " " << str[l1 + l + 1] << " " << str[l2 + l + 1] << endl; return str[l1 + l] > str[l2 + l]; } LL tree[maxn][maxn]; void update(LL *tr,int t,LL p){ for(;t <= N ; t += t & -t) tr[t] = (tr[t] + p) % mod; } LL getsum(LL *tr,int p){ LL ans = 0; for(;p > 0; p -= p & -p) ans = (ans + tr[p]) % mod; return ans; } int main(){ Sca(N); scanf("%s",str + 1); for(int i = 1; i <= N ; i ++){ pre_EKMP(str + i,N - i + 1,nxt[i] + i); } update(tree[1],1,1); for(int i = 1; i <= N ; i ++){ if(str[i] == ‘0‘) continue; for(int j = 1; j < i ; j ++){ if(str[j] == ‘0‘) continue; int len = i - j; LL x = getsum(tree[j],i - 1); if(!x) continue; int r = i + len - 3; while(r <= N && !cmp(i,r,j,i - 1)) r++; //cout << j << " " << i - 1 <<"update" << i << " " << r << " " << endl; update(tree[i],x); } } LL ans = 0; for(int i = 1; i <= N ; i ++) ans = (ans + getsum(tree[i],N)) % mod; Prl(ans); return 0; }
E.将题目的难度从大到小排序,然后枚举
排序三人做题能力为c > b > a
每次遇到的当前最难的题按照想让c做,不行就让a + b做然后依次轮到a + c,b +c,a + b + c来做。
除了第一种情况,其余的都只存在一个人或没有人再空余,让那个人去做当前最难的他能做的题目。
第一种情况,如果b能单独切一道题就让a,b分开切,否则就让a,b合起来做题,用平衡树或multiset直接维护这个过程
#include <map> #include <set> #include <ctime> #include <cmath> #include <queue> #include <stack> #include <vector> #include <string> #include <bitset> #include <cstdio> #include <cstdlib> #include <cstring> #include <sstream> #include <iostream> #include <algorithm> #include <functional> using namespace std; #define For(i,f = 1;char c = getchar();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 double eps = 1e-9; const int maxn = 2e5 + 10; const int INF = 0x3f3f3f3f; const int mod = 1e9 + 7; int N,K; struct Node{ int a[4]; int num; Node(){} Node(int n,int A,int B = INF,int C = INF){ num = n; a[1] = A; a[2] = B; a[3] = C; } }node[100]; int a,b,c; int Hash[maxn * 2]; int x[maxn]; int cnt = 0; int tree[maxn]; void update(int t,int p){ for(;t > 0; t -= t & -t) tree[t] += p; } int getsum(int t){ int ans = 0; for(;t <= cnt;t += t & -t) ans += tree[t]; return ans; } multiset<int>Q; int main(){ Sca(N); cnt = 0; scanf("%d%d%d",&a,&b,&c); if(c < b) swap(c,b); if(b < a) swap(b,a); if(c < b) swap(c,b); for(int i = 1; i <= N; i ++){ Sca(x[i]); if(x[i] > a + b + c){ puts("-1"); return 0; } } for(int i = 1; i <= N ; i ++) Q.insert(x[i]); Q.insert(-INF); Q.insert(INF); node[1] = Node(3,c,a); node[2] = Node(2,a + b,c); node[3] = Node(2,a + c,b); node[4] = Node(2,c + b,a); node[5] = Node(1,a + b + c); int ans = 0; while(Q.size() > 2){ set<int>::iterator it = Q.end(); it--; it--; for(int i = 1; i <= 5; i ++){ if(node[i].a[1] < (*it)) continue; ans++; Q.erase(it); if(i == 1){ it = Q.upper_bound(node[i].a[2]); it--; if((*it) == -INF){ it = Q.upper_bound(b + a);it--; if((*it) != -INF) Q.erase(it); }else{ Q.erase(it); it = Q.upper_bound(node[i].a[3]); it--; if((*it) != -INF) Q.erase(it); } }else{ if(node[i].num == 2){ it = Q.upper_bound(node[i].a[2]); it--; if((*it) != -INF) Q.erase(it); } } break; } } Pri(ans); return 0; }
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。