标签:fas efi vector min ret href partition 相同 https
E
题意真的是看瞎眼,题意:要输出每个位置i—th使得求出q1~q(i-1)有效的情况下答案是多少;
每次在i-th操作,我们要执行将p1,p2.p3依次放进空集里面,那么轮到q位置,例如q=5,那就是第五个p数字
他就要爆炸,使得这个集合最大的元素炸飞,然后执行完q1~q(i-1)后,该集合的最大元素是谁
那么第i—th个输出的就是这个元素;
那么我们应该怎么做呢,我们首先先发现这个最后输出的序列肯定是个单调不递增,那么!!
那么就会发现我们是不是可以考虑从头到尾直接从大到小枚举,只要满足条件,那就输出!!
那现在看一下是什么条件,我们假定该位置的正确答案本来应该是x,那么现在我们是从大到小枚举,枚举到了一个大于x的,
但是实际上答案是x的,枚举到大于x的要被一个判断条件将这个大于的给pass掉,怎么pass掉呢?
想当然这个大于x的之所以不是答案是因为他被炸掉了,被炸掉了说明在前i个q操作中,必须有一次操作操作到这个大于x的位置的右边
使得他会被炸掉,至少有一个炸弹,有多少个无所谓;
接下来就是讨论怎么做,我们知道从第1个到第i个,是有叠加性的,前面的处理后可以到后面接着用
我们知道一个炸弹位置,例如在k位置,他只会影响1到k这里的最大数,而我们又是从大到小
枚举,那么我们只要每次炸弹操作都将一个区间给给覆盖-1,不过毕竟第i个输出不会用到第i个q,所以我们先更新当前第
i个入队数字的区间全部++,判断1到n区间是否有1,没1说明这个数字的位置覆盖位置无法超过q炸弹的影响位置
难逃一吸,那就只能--,寻找这个新的x位置有1说明当前数字x可以覆盖掉炸弹位置也就是前i个操作的炸弹这次没法炸到这个个位置,那就输出
#include<iostream> #include<string> #include<string.h> #define lson rt<<1 #define rson rt<<1|1 using namespace std; typedef long long ll; typedef pair<int, int> P; const int maxn=3e5+10; int tree[maxn<<2],lazy[maxn<<2],a[maxn],p[maxn],id[maxn]; void pushdown(int rt) { tree[lson]+=lazy[rt]; tree[rson]+=lazy[rt]; lazy[lson]+=lazy[rt]; lazy[rson]+=lazy[rt]; lazy[rt]=0; } void pushup(int rt) { tree[rt]=max(tree[lson],tree[rson]); } void update(int L,int R,int x,int l,int r,int rt) { if(L<=l&&r<=R) { tree[rt]+=x; lazy[rt]+=x; return; } pushdown(rt); int mid=(l+r)/2; if(L<=mid) update(L, R, x,l, mid, lson); if(mid<R) update(L, R, x,mid+1, r, rson); pushup(rt); } int q(int L,int R,int l,int r,int rt) { pushdown(rt); if(L<=l&&r<=R) { return tree[rt]; } int mid=(l+r)/2; int ans=0; if(L<=mid) ans=max(ans,q(L, R, l, mid, lson)); if(mid<R) ans=max(ans,q(L, R, mid+1, r, rson)); return ans; } int n; int main() { cin>>n; for(int i=1;i<=n;i++){ cin>>a[i]; id[a[i]]=i; } for(int i=1;i<=n;i++) cin>>p[i]; int now=n; update(1,id[n], 1, 1, n ,1); for(int i=1;i<=n;i++) { cout<<now<<" "; if(i==n) break; update(1, p[i], -1, 1, n, 1); while(q(1, n, 1, n, 1)<=0) { now--; update(1,id[now], 1, 1, n, 1); } } }
题意:
给出一个字符串ss。
现在要找到一个最长的串tt,满足:
思路:
可以注意到若ss串首尾字符相同,那么我们可以直接去除不影响答案。
简要证明:
#include <bits/stdc++.h> #define pb(x) push_back(x) #define mp(x, y) make_pair(x, y) #define fast ios::sync_with_stdio(false) #define mset(a, n) memset(a, n, sizeof(a)) #define forn(i, n) for (int i = 0; i < (n); ++i) #define forab(i, a, b) for (int i = (a); i <= (b); ++i) #define forba(i, b, a) for (int i = (b); i >= (a); --i) #define db double #define ll long long #define endl ‘\n‘ #define fi first #define se second using namespace std; typedef pair<int, int> P; inline int lowbit(int x) { return x & (-x); } const ll MOD = 1e9 + 7; const ll mod = 998244353; string Manacher(string &s) { string t = "$#"; for (int i = 0; i < s.length(); ++i) { t += s[i]; t += ‘#‘; } int ml = 0, p = 0, R = 0, M = 0; int len = t.length(); vector<int> P(len, 0); for (int i = 0; i < len; ++i) { P[i] = R > i ? min(P[2 * M - i], R - i) : 1; while (t[i + P[i]] == t[i - P[i]]) ++P[i]; if (i + P[i] > R) { R = i + P[i]; M = i; } if (ml < P[i] && (i - P[i]) / 2 == 0) { ml = P[i]; p = i; } } return s.substr((p - ml) / 2, ml - 1); } int main(){ fast; int t; cin >> t; while (t--) { string s; cin >> s; int l = 0, r = s.size() - 1; while (s[l] == s[r] && l < r) ++l, --r; string pre = s.substr(0, l), suf = s.substr(r + 1); //cout << pre << " " << suf << "\n"; string ss = s.substr(l, r - l + 1); string ex = Manacher(ss); reverse(ss.begin(), ss.end()); string exx = Manacher(ss); //cout << ss << " " << ex << " " << exx << "\n"; if (ex.length() > exx.length()) cout << pre + ex + suf << "\n"; else cout << pre + exx + suf << "\n"; } return 0; }
题意:感觉题目稍微有点绕,给定一个 1−n1−n 上的全排列,将这个全排列分成不相交的 kk 段,定义该划分的 valuevalue 为各段最大值的和,求该全排列所有可能划分中 valuevalue 的最大值和达到最大值的划分情况个数。
思路:读懂题目之后思路其实就出来了,1−n1−n 的全排列分成 kk 段,显然最大的 valuevalue 为前 kk 大的数之和,至于满足情况的个数,从小到大记录前 kk 个数出现的位置,每次将答案乘以相邻两数位置之差就是答案,这题两发才过,第一发我模数写错了真是***了。
#include <bits/stdc++.h> #define pb(x) push_back(x) #define mp(x, y) make_pair(x, y) #define fast ios::sync_with_stdio(false) #define mset(a, n) memset(a, n, sizeof(a)) #define forn(i, n) for (int i = 0; i < (n); ++i) #define forab(i, a, b) for (int i = (a); i <= (b); ++i) #define forba(i, b, a) for (int i = (b); i >= (a); --i) #define db double #define ll long long #define endl ‘\n‘ #define fi first #define se second using namespace std; typedef pair<int, int> P; inline int lowbit(int x) { return x & (-x); } const ll MOD = 1e9 + 7; const ll mod = 998244353; vector<ll> v; int main(){ fast; ll n, k; cin >> n >> k; ll ans = 0, cnt = 1; forab(i, 1, n){ int x; cin >> x; if (x > (n - k)){ v.push_back(i); ans += x; } } for (int i = 0; i < v.size() - 1; ++i) { cnt = cnt * (v[i + 1] - v[i]) % mod; } cout << ans << " " << cnt << "\n"; return 0; }
标签:fas efi vector min ret href partition 相同 https
原文地址:https://www.cnblogs.com/hgangang/p/12552811.html