test20231029

T1

经典题目加上一点变形。

如果说不是序列而是询问有多少个子串,那么有一个非常经典的方程:

\(f_{i,j}\) 为到第 \(i\) 位,前面有 \(j\) 个多的 (

$f_{i,j}=f_{i,j}+f_{i-1,j-1} \quad $ \(s_i=\) (||?

$f_{i,j}=f_{i,j}+f_{i-1,j+1} \quad $ \(s_i=\) ||?

那么,如果是询问子序列呢,想一想,其实只不过是多了一种转移:

\(f_{i,j}=f_{i-1,j}\)

那么这道题就解决了。

int f[5050][5050];
char s[N];
int n;
int sum[5050][5050];
signed main(){
    freopen("bracket.in", "r", stdin);
    freopen("bracket.out", "w", stdout);
	n=read();
    scanf("%s",s+1);
    sum[0][0]=1;f[0][0]=1;
    sum[1][0]=1;f[1][0]=1;
    up(i,1,n){
        up(j,0,n){
            f[i][j]=f[i-1][j];
            if(j!=0&&(s[i]=='('||s[i]=='?')){
                f[i][j]=(sum[i-1][j-1]+f[i][j])%mod;
            }
            if((s[i]==')'||s[i]=='?')){
                f[i][j]=(sum[i-1][j+1]+f[i][j])%mod;
            }
            sum[i][j]=f[i][j]%mod;
        }
    }
    cout<<sum[n][0];
    return 0;
}

T2

蒸蒸日上。

注意到 \(m\) 十分的大, 如果把所有武将都全部升级肯定最优,因为每个武将都可以产生大于升级它所需代价的收益。

正着算不是很好算,我们可以将全部收益减去升级之前的收益,也就是说如果一个装置在第 \(j\) 分钟成功升了一级,那么就从总收益中减去 \(j\) 的收益。

题意转化为 \(n\) 个数组 \(a_i\),要将所有元素重排进 长度为 \(\sum k_i\) 数组 \(b\),使得 \(b\) 数组中的元素顺序满足在 \(a_i\) 数组中的顺序关系,并且使得 \(b\) 数组的前缀和的和最小。

如果不考虑 \(a\) 数组的限制关系,显然是直接将所有数排个序,可以使前缀和的和最小。

更一般的,我们设想 \(b\) 数组中的两段数,第一段数排在第二段前的充要条件,显然是第一段数的平均值小于第二段数。

所以我们要做的,是每次把所有 \(a_i\) 中最小平均值的一段数拿出来,放到 \(b\) 数组中去。

将每个 \(a\) 数组提前分好段,这样的段在每个 \(a\) 数组中的平均值都是单调递增的,就转化为所有元素都递增的的情况,直接排序就好了。

怎么分段呢?我们每次在当前段加入一个数,如果这一段平均值变小,就合并,否则继续。但这样的数列 \(9,8,7,6,10,1,1,1\) 前四个数的平均值大于后四个数,还要再做一次,这样最劣要从前往后做 \(n\) 次,复杂度 \(O(n^2)\)

我们发现,当加入一个数时,如果平均值不变小,就可以和上一段比,如果上一段平均值比这一段平均值大,那么往前合并,然后将下一个数当做一个新段。因为每合并一次就会少一段,所以这这样做 \(O(n)\) 的。

瓶颈在排序,复杂度 \(O(nlogn)\)

T3

看到序列,端点,两个限制条件,

很一眼二维数点。

先用单调栈维护出每一个点向左向右分别最多能够扩展的距离。

\(i\) 为左端点,所有的右端点需要满足条件 \(R_i\le j\le n\)\(i\le L_j\)

所以我们建立二维平面,以 \(i\) 为横坐标,\(L_i\) 为纵坐标询问的区间就是 \([R_i,i,n,n]\)

右端点的情况下同理。

然而,由于一些玄学问题我这个题用 sort 无法通过,但是用 stable_sort 却可以通过。

?????????

image

int n,id;
int a[N];
struct Bit{
    int tr[M];
    inline void add(int x,int val){
        if(x==0)return;
        for(;x<n+10;x+=x&(-x))tr[x]+=val;
    }
    inline int sum(int x){
        int res=0;
        for(;x;x-=x&(-x))res+=tr[x];
        return res;
    }
    inline void init(){
        memset(tr,0,sizeof tr);
    }
}T; 
int s[N],top;
int Lmin[N],Lmax[N],Rmin[N],Rmax[N];
int L[N],R[N];
struct node{
    int op,x,y,add,id;
}p[N<<1];
int cnt;
inline bool cmp(node aa, node bb){
    if (aa.x != bb.x)return aa.x<bb.x;
    else if (aa.op != bb.op)return aa.op<bb.op;
    return aa.y < bb.y;
}
int ans1[N],ans2[N];
inline void solve2(){
	cnt=0;
    up(i,1,n){
        p[++cnt]={0,i,R[i]+1,0,0};
    }
    up(i,1,n){
        if(L[i]<1)continue;
        p[++cnt]={1,L[i],i+1,1,i};
    }
    stable_sort(p+1,p+1+cnt,cmp);
    T.init();
    up(i,1,cnt){
        if (!p[i].op)T.add(p[i].y,1);
        else {
            ans2[p[i].id]+=p[i].add*T.sum(p[i].y);
        }
    }
}
signed main(){
    freopen("interval.in","r",stdin);
	freopen("interval.out","w",stdout);
    n=read();id=read();
    up(i,1,n){
        a[i]=read();
    }
    top=0;
    up(i,1,n){
        while(top&&a[s[top]]<=a[i])top--;
        Lmax[i]=s[top];
        s[++top]=i;
    }
    top=0;
    up(i,1,n){
        while(top&&a[s[top]]>=a[i])top--;
        Lmin[i]=s[top];
        s[++top]=i;
    }
    up(i,1,n)L[i]=min(Lmax[i],Lmin[i]);
    top=0;
    s[top]=n+1;
    dn(i,n,1){
        while(top&&a[s[top]]<=a[i])top--;
        Rmax[i]=s[top];
        s[++top]=i;
    }
    top=0;
    s[top]=n+1;
    dn(i,n,1){
        while(top&&a[s[top]]>=a[i])top--;
        Rmin[i]=s[top];
        s[++top]=i;
    }
    up(i,1,n)R[i]=max(Rmax[i],Rmin[i]);
    solve2();
	cnt=0;
    up(i,1,n){
	 	p[++cnt]={0,n+1-i,n+1-L[i]+1,0,0};
        if(n+1-R[i]<1)continue;
        p[++cnt]={1,n+1-R[i],n+1-i+1,1,i};
    }
    stable_sort(p+1,p+1+cnt,cmp);
    T.init();
	up(i,1,cnt){
        if (!p[i].op)T.add(p[i].y,1);
        else ans1[p[i].id]+=p[i].add*T.sum(p[i].y);
    }
    up(i,1,n){
        write(ans1[i],0);
    }
    printf("\n");
    up(i,1,n){
        write(ans2[i],0);
    }
    return 0;
}

posted @ 2023-10-30 22:03  LiQXing  阅读(31)  评论(0)    收藏  举报