标签: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