北理的18级比我校17级还猛,这上哪儿说理去
A.发现存在长度相等的棒子答案最小值就是0,直接特判
时间复杂度从n ^ 2优化到40 * 40
(一开始没想到 写着分段二分WA7发)
#include <map> #include <set> #include <ctime> #include <cmath> #include <queue> #include <stack> #include <vector> #include <string> #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, x, y) for(int i=x;i>=y;i--) #define Mem(f, x) memset(f,x,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",&x,&y,&z) #define Scl(x) scanf("%lld",&x); #define Pri(x) printf("%d ", x) #define Prl(x) printf("%lld ",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-6; const int maxn = 1e5 + 10; const int INF = 0x3f3f3f3f; const int mod = 1e9 + 7; int N,M,K; struct node{ int fi,se,id; }; node a[maxn]; bool cmp(node a,node b){ return a.id < b.id; } int MAX[50],MIN[50]; struct fen{ LL son,mon; fen(){} fen(LL son,LL mon):son(son),mon(mon){} friend bool operator < (fen a,fen b){ return a.son * b.mon < b.son * a.mon; } friend bool operator == (fen a,fen b){ return (a.son * b.mon) == (b.son * a.mon); } }; vector<int>Q[50]; int main(){ Sca(N); for(int i = 1; i <= N ; i ++){ a[i].fi = read(); a[i].se = read(); Q[a[i].fi].push_back(i); a[i].id = i; } int u = INF,v = INF; bool flag = 0; for(int i = 1; i <= 40; i ++){ if(Q[i].size() > 1){ flag = 1; int uu = Q[i][0],vv = Q[i][1]; if(uu < u || (uu == u && vv < v)){ u = uu; v = vv; } } } if(flag){ printf("%d %d",u,v); return 0; } fen ans = fen(INF,1); sort(a + 1,a + 1 + N,cmp); for(int i = 1; i <= N ; i ++){ for(int j = i + 1; j <= N ; j ++){ fen x = fen(max(a[i].se,a[j].se) * abs(a[j].fi - a[i].fi),min(a[i].se,a[j].se)); if(x < ans){ ans = x; u = a[i].id,v = a[j].id; } } } printf("%d %d ",u,v); return 0; }
B.没啥好说的,找了规律暴力模拟,只要有耐心就能写出来的题
#include <map> #include <set> #include <ctime> #include <cmath> #include <queue> #include <stack> #include <vector> #include <string> #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, x, y) for(int i=x;i>=y;i--) #define Mem(f, x) memset(f,x,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",&x,&y,&z) #define Scl(x) scanf("%lld",&x); #define Pri(x) printf("%d ", x) #define Prl(x) printf("%lld ",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 = 510; const int INF = 0x3f3f3f3f; const int mod = 1e9 + 7; int a,b,c; char MAP[maxn][maxn]; int main(){ int T; Sca(T); while(T--){ Sca3(a,b,c); int w = 2 * a + 1 + 2 * b; int h = 2 * c + 1 + 2 * b; for(int i = 1; i <= h; i ++ ){ for(int j = 1; j <= w; j ++) MAP[i][j] = '?'; } for(int i = 1; i <= h; i ++){ for(int j = 1; j <= w ; j ++){ if(h - i + j <= 2 * b) MAP[i][j] = '.'; if(i + w - j <= 2 * b) MAP[i][j] = '.'; } } int l = min(h / 4,b); /*for(int i = 3; i <= h;i += 2){ int x = min(i,h - i + 1); x /= 2; x = min(x,b); if(i < h - i + 1){ for(int j = 1; j <= x; j++){ MAP[i][j * 2] = 'p'; } }else{ for(int j = l; j >= l - x + 1; j --){ MAP[i][j * 2] = 'p'; } } } */ for(int i = 2; i <= 2 * b; i += 2){ for(int j = i + 1; j <= w; j += 2) MAP[i][j] = '.'; } for(int i = 2 * b + 2; i <= h; i += 2){ for(int j = 2 * b + 2; j <= w; j += 2) MAP[i][j] = '.'; } for(int i = 1; i <= h; i += 2){ for(int j = 1; j <= w; j ++){ if(MAP[i][j] == '.' || MAP[i][j] == 'p') continue; int cnt = 0; if(2 * b >= i - 1){ cnt = 2 * b - i + 1; } if(j & 1) MAP[i][j] = '+'; else if(w - j + 1 - cnt <= 2 * a){ MAP[i][j] = '-'; } else MAP[i][j] = '.'; } } for(int i = 2; i <= h ; i += 2){ for(int j = 1; j <= w; j ++){ if(MAP[i][j] == '.') continue; if(j & 1) MAP[i][j] = '|'; else MAP[i][j] = '\'; } } for(int i = 1; i <= h; i ++){ for(int j = 1; j <= w; j ++){ cout << MAP[i][j]; } if(i == h && !T) continue; else cout << endl; } } return 0; }
C.暴力判11个位置插入的符号,(不插入,+,-,*)四种情况,然后表达式求值判断,时间复杂度4 ^ 11 * 24
常数很大,我又菜,表达式求值写的跟*一样自己都看不下去了,手写了个栈才卡过去
#include <map> #include <set> #include <ctime> #include <cmath> #include <queue> #include <stack> #include <vector> #include <string> #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, x, y) for(int i=x;i>=y;i--) #define Mem(f, x) memset(f,x,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",&x,&y,&z) #define Scl(x) scanf("%lld",&x); #define Pri(x) printf("%d ", x) #define Prl(x) printf("%lld ",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; LL y; char Stack[maxn]; int cnt,tot; int ans = 0; char str[20]; PIL S[maxn]; bool check(){ int top = 0; LL num = 0; bool flag = 0; for(int i = 1; i <= tot; i ++){ if(Stack[i] >= '0' && Stack[i] <= '9'){ if(!num && flag) return 0; num = num * 10 + Stack[i] - '0'; flag = 1; }else if(Stack[i] == '-'){ if(flag){ while(top && S[top].fi == 2 && S[top].se == 3){ top--; num *= S[top].se; top--; } S[++top] = mp(1,num); num = 0; } S[++top] = mp(2,1); flag = 0; }else if(Stack[i] == '+'){ if(flag){ while(top && S[top].fi == 2 && S[top].se == 3){ top--; num *= S[top].se; top--; } S[++top] = mp(1,num); num = 0; } S[++top] = mp(2,2); flag = 0; }else if(Stack[i] == '*'){ if(flag){ while(top && S[top].fi == 2 && S[top].se == 3){ top--; num *= S[top].se; top--; } S[++top] = mp(1,num); num = 0; } S[++top] = mp(2,3); flag = 0; } } if(flag){ while(top && S[top].fi == 2 && S[top].se == 3){ top--; num *= S[top].se; top--; } S[++top] = mp(1,num); num = 0; } LL ans = 0; while(top){ PIL u = S[top]; top--; if(!top){ ans += u.se; break; } if(S[top].se == 1) ans -= u.se; else ans += u.se; top--; } // if(ans == y){ // for(int i = 1; i <= tot; i ++){ // printf("%c",Stack[i]); // } // puts(""); // } return ans == y; } void dfs(int pos){ Stack[++tot] = str[pos]; if(pos == cnt){ if(check()) ans++; tot--; return; } Stack[++tot] = '-'; dfs(pos + 1); tot--; Stack[++tot] = '+'; dfs(pos + 1); tot--; Stack[++tot] = '*'; dfs(pos + 1); tot--; dfs(pos + 1); tot--; } int main(){ scanf("%s",str); Scl(y); tot = 0; cnt = strlen(str) - 1; dfs(0); Pri(ans); return 0; }
D.搞个优先队列按照还剩下字母多少排序,每次输出剩下字母最多的那个字母
如果有一种字母的数量超过了一半左右就NO
#include <map> #include <set> #include <ctime> #include <cmath> #include <queue> #include <stack> #include <vector> #include <string> #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, x, y) for(int i=x;i>=y;i--) #define Mem(f, x) memset(f,x,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",&x,&y,&z) #define Scl(x) scanf("%lld",&x); #define Pri(x) printf("%d ", x) #define Prl(x) printf("%lld ",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 = 1e5 + 10; const int INF = 0x3f3f3f3f; const int mod = 1e9 + 7; int N,M,K; char str[maxn]; int num[30]; struct node{ int id,n; node(){} node(int id,int n):id(id),n(n){} friend bool operator < (node a,node b){ return a.n < b.n; } }; int main(){ scanf("%s",str); int MAX = 0,l = strlen(str); for(int i = 0;str[i]; i ++) num[str[i] - 'a']++; for(int i = 0 ; i < 26; i ++) MAX = max(MAX,num[i]); if((l & 1) && (MAX > l / 2 + 1)){ puts("NO"); return 0; } if(!(l & 1) && (MAX > l / 2)){ puts("NO"); return 0; } priority_queue<node>Q; for(int i = 0 ; i < 26; i ++){ if(num[i]) Q.push(node(i,num[i])); } int la = 100; while(!Q.empty()){ node u = Q.top(),v; Q.pop(); if(la == u.id){ v = Q.top(); Q.pop(); Q.push(u); u = v; } printf("%c",u.id + 'a'); u.n--; la = u.id; if(u.n > 0) Q.push(u); } return 0; }
E.求和公式都会8,(a[1] + a[1] + n - 1) * n = 2 * N
枚举一下n,判断a[1]是否符合条件,时间复杂度根号N
#include <map> #include <set> #include <ctime> #include <cmath> #include <queue> #include <stack> #include <vector> #include <string> #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, x, y) for(int i=x;i>=y;i--) #define Mem(f, x) memset(f,x,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",&x,&y,&z) #define Scl(x) scanf("%lld",&x); #define Pri(x) printf("%d ", x) #define Prl(x) printf("%lld ",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; LL N,X; int check(LL i){ if((N / i - i + 1) & 1) return 0; LL a = (N / i - i + 1) / 2; return a > 0; } int main(){ int T; Sca(T); while(T--){ Scl(X); //ll N = X * 2; int ans = 0; for(LL i = 1; i * i <= N; i ++){ if(N % i) continue; ans += check(i); if(i * i != N) ans += check(N / i); } Pri(ans); } return 0; }
F.提供一手敲了一个多小时的CE代码
个人觉得本题的正解是离散化之后上线段树区间求和区间修改,问题在于mod 2 ^ 64的这个操作ULL都存不下,大数模板里也没有对大数取模这个操作
我个人觉得__int128可以过,但是gym这个oj的所有提交语言都CE了__int128,这让敲了一个小时的我上哪里说理去。
或许出题人把mod设置为2 ^ 64的意思是让我开64颗线段树按位处理?
后记:晚上睡觉的时候突然开始想出题人为什么要出(1 << 64)这么一个奇怪的取模数
他肯定不是为了开大数,一定有他自己的一套想法,说起来这个数似乎挺特殊的
这不是unsigned long long 自动取模的那个数吗?
操
现在的代码可以AC了
#include <map> #include <set> #include <ctime> #include <cmath> #include <queue> #include <stack> #include <vector> #include <string> #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, x, y) for(int i=x;i>=y;i--) #define Mem(f, x) memset(f,x,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",&x,&y,&z) #define Scl(x) scanf("%lld",&x); #define Pri(x) printf("%d ", x) #define Prl(x) printf("%lld ",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; LL read(){LL 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 = 8e5 + 10; LL N; int M; struct Query{ int op; LL a,b,c; }query[maxn]; LL Hash[maxn * 2]; struct Tree{ int l,r; ULL sum,lazy; }tree[maxn * 4]; void Build(int t,int l,int r){ tree[t].l = l; tree[t].r = r; tree[t].sum = tree[t].lazy = 0; if(r - l <= 1) return; int m = l + r >> 1; Build(t << 1,l,m); Build(t << 1 | 1,m,r); } void Pushup(int t){ tree[t].sum = tree[t << 1].sum + tree[t << 1 | 1].sum; } void solve(int t,ULL p){ tree[t].lazy = p + tree[t].lazy; tree[t].sum = tree[t].sum + ((ULL)Hash[tree[t].r] - (ULL)Hash[tree[t].l]) * p; } void Pushdown(int t){ if(tree[t].lazy){ solve(t << 1,tree[t].lazy); solve(t << 1 | 1,tree[t].lazy); tree[t].lazy = 0; } } void update(int t,int l,int r,ULL p){ if(l <= tree[t].l && tree[t].r <= r){ solve(t,p); return; } Pushdown(t); int m = (tree[t].l + tree[t].r) >> 1; if(r <= m) update(t << 1,l,r,p); else if(l >= m) update(t << 1 | 1,l,r,p); else{ update(t << 1,l,m,p); update(t << 1 | 1,m,r,p); } Pushup(t); } ULL _query(int t,int l,int r){ if(l <= tree[t].l && tree[t].r <= r){ return tree[t].sum; } Pushdown(t); int m = (tree[t].l + tree[t].r) >> 1; if(r <= m) return _query(t << 1,l,r); else if(l >= m) return _query(t << 1 | 1,l,r); else{ return _query(t << 1,l,m) + _query(t << 1 | 1,m,r); } } int main(){ cin >> N >> M; int cnt = 0; for(int i = 1; i <= M; i ++){ query[i].op = read(); query[i].a = read(); query[i].b = read(); if(query[i].op == 1) query[i].c = read(); Hash[++cnt] = query[i].a; // Hash[++cnt] = query[i].b; Hash[++cnt] = query[i].b + 1; } sort(Hash + 1,Hash + 1 + cnt); cnt = unique(Hash + 1,Hash + 1 + cnt) - Hash - 1; Build(1,1,cnt); for(int i = 1; i <= M; i ++){ query[i].a = lower_bound(Hash + 1,Hash + 1 + cnt,query[i].a) - Hash; query[i].b = lower_bound(Hash + 1,Hash + 1 + cnt,query[i].b + 1) - Hash; if(query[i].op == 1) update(1,query[i].a,query[i].b,query[i].c); else{ ULL ans = _query(1,query[i].a,query[i].b); cout << ans << endl; } } return 0; }
K.喜闻乐见数位dp
太久没敲了水平菜的要死,敲出来的数位dp我自己都看不下去了
#include <map> #include <set> #include <ctime> #include <cmath> #include <queue> #include <stack> #include <vector> #include <string> #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, x, y) for(int i=x;i>=y;i--) #define Mem(f, x) memset(f,x,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",&x,&y,&z) #define Scl(x) scanf("%lld",&x); #define Pri(x) printf("%d ", x) #define Prl(x) printf("%lld ",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 = 20; const int INF = 0x3f3f3f3f; const int mod = 1e9 + 7; int N,M,K; int str[maxn]; LL dp[maxn][12]; LL ten[maxn],c[maxn]; LL dfs(int pos,LL num,int limit){ if(pos == 0) return num; if(~dp[pos][num] && !limit) return dp[pos][num]; int top = limit?str[pos - 1]:9; LL ans = 0; for(int i = 0 ; i <= top; i ++){ ans += dfs(pos - 1,i,str[pos - 1] == i && limit); } if(limit) ans += num * (c[pos - 1] + 1); else ans += num * ten[pos]; if(!limit) dp[pos][num] = ans; return ans; } LL solve(LL x){ if(!x) return 0; Mem(dp,-1); int cnt = 0; while(x){ if(!cnt) c[cnt] = x % 10; else c[cnt] = ten[cnt] * (x % 10) + c[cnt - 1]; str[cnt++] = x % 10; x /= 10; } str[cnt] = 0; LL ans = dfs(cnt,0,1); return ans; } int main(){ ten[0] = 1; for(int i = 1; i <= 17; i ++) ten[i] = ten[i - 1] * 10; LL l,r; scanf("%lld%lld",&l,&r); Prl(solve(r) - solve(l - 1)); return 0; }