2019徐州网络赛 I J M

I. query

  • 比赛时候没有预处理因子疯狂t,其实预处理出来因子是\(O(nlog(n))\)级别的
  • 每个数和他的因子是一对偏序关系,因此询问转化为(l,r)区间每个数的因子在区间(l,r)的个数
  • 预处理出来每个位置上的数所有因子的位置,用可持久化线段树维护,区间询问
#include<bits/stdc++.h>
#define ll long long
#define mk make_pair
#define ft first
#define se second
#define pii pair<int,int>
#define db double
#define ls o<<1
#define rs o<<1|1
#define lowbit(x) (x&-x)
using namespace std;
const int M=1e5+5;
int V[M*200];
int lch[M*200],rch[M*200];
int rt[M],tot=0;
vector<int>fac[M];
int p[M],a[M];
int n,m;
void init(int N){
    for(int i=1;i<=N;i++){
        for(int j=2*i;j<=N;j+=i)
            fac[j].push_back(i);
    }
}

void upd(int &o,int pre,int l,int r,int p){
    o=++tot;
    V[o]=V[pre];
    lch[o]=lch[pre];
    rch[o]=rch[pre];
    if(p==0||l==r){
        V[o]++;
        return ;
    }
    int mid=(l+r)/2;
    if(p<=mid)
        upd(lch[o],lch[pre],l,mid,p);
    else
        upd(rch[o],rch[pre],mid+1,r,p);
    V[o]=V[lch[o]]+V[rch[o]];
}
int qy(int o,int pre,int l,int r,int L,int R){
    if(!o)
        return 0;
    if(L<=l&&r<=R)
        return V[o]-V[pre];
    int mid=(l+r)/2;
    int ans=0;
    if(L<=mid)
        ans+=qy(lch[o],lch[pre],l,mid,L,R);
    if(R>mid)
        ans+=qy(rch[o],rch[pre],mid+1,r,L,R);
    return ans;
}
int main(){
    cin>>n>>m;
    init(n);
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
        p[a[i]]=i;
    }
    for(int i=1;i<=n;i++){
        upd(rt[i],rt[i-1],1,n,0);
        for(auto v:fac[a[i]])
            upd(rt[i],rt[i],1,n,p[v]);
    }
    while(m--){
        int l,r;
        scanf("%d%d",&l,&r);
        printf("%d\n",qy(rt[r],rt[l-1],1,n,l,r));
    }
    return 0;
}

J. Random Access Iterator

  • 需要计算能成功走到最深节点的概率,对于每个节点,有k次尝试机会,显然计算连续失败k次的概率比较简单
  • \(dp[u]\)代表从u往下走失败的概率,转移为\(dp[u]=(\frac{1}{sz[son]} \Sigma_{son} dp[v])^{sz[son]}\),答案为\(1-dp[root]\)
  • 预处理出来每个节点的高度
  • 树形概率从叶子往上推

M. Longest subsequence

  • 字典序需要严格大于T,意味着下面两种情况满足任一种即可

    • 选出的子序列s只要某一位对应T大,后面的可全选
    • 子序列s所有位和T一样,那么s要比T长
  • 对S贪心,肯定选出的位置越左越好
    • 若S[i]>T[j],则S后面都可以选
    • 若S[i]<T[j],该位不符合要求不能选
    • 若S[i]==T[j],则在S中找到i后面第一个比T[j+1]大的位置更新答案
  • 处理出S[i]后面第一个c可以用序列自动机
#include<bits/stdc++.h>
#define ll long long
#define mk make_pair
#define ft first
#define se second
#define pii pair<int,int>
#define db double
#define ls o<<1
#define rs o<<1|1
#define lowbit(x) (x&-x)
using namespace std;
const int M=1e6+5;
int f[M][27],w[27];
int n,m;
char s[M],t[M];
int main(){
    scanf("%d%d",&n,&m);
    scanf("%s%s",s,t);
    for(int i=0;i<26;i++)
        w[i]=-1;
    for(int i=n-1;i>=0;i--){
        for(int j=0;j<26;j++)
            f[i][j]=w[j];
        w[s[i]-'a']=i;
    }
    int ans=-1;
    for(int i=t[0]-'a'+1;i<26;i++){
        if(f[0][i]>=0){
            ans=max(ans,n-f[0][i]);
        }
    }
    int p=0;
    for(int i=0;i<n;i++){
        if(s[i]<t[p])continue;
        if(s[i]>t[p])break;
        if(p==m-1){
            if(i+1<n)
                ans=max(ans,p+1+n-i-1);
            break;
        }else{
            for(int j=t[p+1]-'a'+1;j<26;j++){
                if(f[i][j]>=0)
                ans=max(ans,p+1+n-f[i][j]);
            }
            p++;
        }
    }
    cout<<ans<<endl;
    return 0;
}

原文地址:https://www.cnblogs.com/VIrtu0s0/p/11511307.html

时间: 2024-07-30 20:33:32

2019徐州网络赛 I J M的相关文章

2019徐州网络赛 XKC&#39;s basketball team 线段树

网址:https://nanti.jisuanke.com/t/41387 题意: 大家好,我是训练时长两年半的个人练习生蔡徐坤,我的爱好是唱,跳,rap,篮球. 给出一段长度为$n,(n \leq 1e5)$的序列,对每一个数,求出它和它后面比它大$m$的数中间夹着的数的数量,没有输出$-1$. 题解: 直接建线段树,维护最大值,然后查询时对第$i$个数,搜索区间$[i,n]$之中大于$num[i]+m$的值的位置的最大值,具体操作是先限定区间,然后求出所有合法位置,取最大值,如果搜索不到则返

query 2019徐州网络赛(树状数组)

query \[ Time Limit: 2000 ms \quad Memory Limit: 262144 kB \] 题意 补题才发现比赛的时候读了一个假题意.... 给出长度为 \(n\) 的排列,在给出 \(m\) 次询问,每次询问有一对 \(l.r\),问满足 \(min(ai, aj) = gcd(ai, aj)\) 的 \(pair(i, j)\) 对数. 思路 考虑离线做 先把每个数出现的位置记录下来,然后预处理出所有的 \(pair\). 对于一个数字 \(x\),其满足条件

【2019.09.07】2019徐州网络赛

补题地址:https://www.jisuanke.com/contest/3005?view=challenges 题目: A:? B:? C:? D:? E:? F: G:? 回文树+二进制统计回文串内不同字母数技巧https://blog.csdn.net/Cassie_zkq/article/details/100606270 H: I:? J: K:? L: M:? 原文地址:https://www.cnblogs.com/ncu2019/p/11482910.html

2019徐州网络赛

I 题 query 题目链接 题目大意是给一个N(<=1e5) permutation  p (下标从1开始) , 现在定义一种pair( i ,j) ,其满足 min(pi?,pj?)=gcd(pi?,pj?),现在有M (<=1e5) 组区间查询[l,r]询问 满足 l <= i < j <= r 的pair有多少对. 这是一种偏序关系的问题,看了一点CDQ 解偏序的介绍 , 感觉也可以树状数组来搞.预处理出每个符合要求的点对( l , r )位置,在一维树状数组上修改点

2019 徐州网络赛 center

题意:n个点,求最小加上几个点让所有点关于一个点(不需要是点集里面的点)中心对称 题解:双重循环枚举,把中点记录一下,结果是n-最大的中点 1 #include <bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 typedef unsigned long long ull; 5 #define mem(s) memset(s, 0, sizeof(s)) 6 const int INF = 0x3f3f3f3f;

2019徐州网络赛 H.function

题意: 先有\(n=p_1^{k_1}p_2^{k_2}\cdots p_m^{k_m}\),定义\(f(n)=k_1+k_2+\cdots+k_m\). 现在计算 \[ \sum_{i=1}^nf(i!)\% 998244353 \] 思路: 首先注意到\(f\)函数有这样一个性质:\(f(ab)=f(a)+f(b)\). 那么我们化简所求式子有: \[ \begin{aligned} &\sum_{i=1}^nf(i!)\=&\sum_{i=1}^n\sum_{j=1}^if(j)\=

20180909徐州网络赛题解

目录 20180909徐州网络赛题解 A. Hard to prepare MEANING SOLUTION CODE B. BE, GE or NE MEANING SOLUTION CODE F. Features Track CODE G. Trace MENING SOLUTION CODE H. Ryuji doesn't want to study MEANING CODE I. Characters with Hash CODE J. Maze Designer MEANING S

2018 ICPC 徐州网络赛

2018 ICPC 徐州网络赛 A. Hard to prepare 题目描述:\(n\)个数围成一个环,每个数是\(0\)~\(2^k-1\),相邻两个数的同或值不为零,问方案数. solution 将环变成链,设\(f[i][0\)~\(2]\),分别表示与第一个数相同,与第一个数不同,与第一个数相同,与第一个数的反相同.然后\(dp\)即可. 时间复杂度:\(O(n)\) B. BE, GE or NE solution 根据题目描述\(dp\)即可. 时间复杂度:\(O(nm)\) C.

2018徐州网络赛H. Ryuji doesn&#39;t want to study

题目链接: https://nanti.jisuanke.com/t/31458 题解: 建立两个树状数组,第一个是,a[1]*n+a[2]*(n-1)....+a[n]*1;第二个是正常的a[1],a[2],a[3]...a[n] #include "bits/stdc++.h" using namespace std; #define ll long long const int MAXN=1e5+10; ll sum[MAXN],ans[MAXN]; ll num[MAXN];