【洛谷八连测R5】whzzt-Warmth

题目描述

题目难度不一定按照题目顺序递增

给定一个序列 S,每次询问这个序列的一个连续子序列的本质不同回文子序列个数。

本质不同的含义是:两个序列不同当且仅当它们的长度不同或存在对应位置不同。

答案可能很大,因此只要输出对 10^9+7 算术取模的值。

输入输出格式

输入格式:

第一行包含一个数据组数 T 。每组数据的格式如下:
第一行包含三个正整数 n,m,k ,表示序列的长度为 n ,询问的次数为 m ,且序列中元素都在 [1,k] 之间。
接下来一行 n 个正整数,第 i 个数表示序列 S 的第 i 个元素 ci。
接下来 m 行,每行两个正整数 li,ri ,表示这次询问的子序列为 S[li..ri]。

输出格式:

输出 m 行,每行一个整数,表示这次询问的结果对 10^9+7 算术取模的值。

说明

代码

85分

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int mo=1e9+7;
const int maxn=2000+5;
typedef long long ll;
inline void read(int &x){
    x=0; char ch=getchar();
    while(ch<'0'||ch>'9') ch=getchar();
    while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
}
int T,n,m,k;
int a[maxn],L[maxn][maxn],R[maxn][maxn],dp[maxn][maxn];
bool vis[maxn][maxn];
int dfs(int x,int y){
    if(vis[x][y]) return dp[x][y];
    if(x>y) return 0;
    ll ans=0;
    for(int i=1;i<=k;++i)
    if(R[x][i]&&L[y][i])
        ans+=dfs(R[x][i]+1,L[y][i]-1)+(R[x][i]<=L[y][i])+(R[x][i]<L[y][i]);
    vis[x][y]=true;
    return dp[x][y]=ans%mo;
}
int main(){
    read(T);
    while(T--){
        read(n);read(m);read(k);
        for(int i=1;i<=n;++i) read(a[i]);
        for(int i=1;i<=n;++i)
            memcpy(L[i],L[i-1],sizeof(L[i-1])),L[i][a[i]]=i;
        for(int i=n;i>=1;--i)
            memcpy(R[i],R[i+1],sizeof(R[i+1])),R[i][a[i]]=i;
        for(int i=1;i<=m;++i){
            int x,y; read(x);read(y);
            printf("%d
",dfs(x,y));
        }
        memset(vis,0,sizeof(vis));
    }
    return 0;
}
    
View Code

100分

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=6000+5;
const int mo=1e9+7;
inline void read(int &x){
    x=0; char ch=getchar();
    while(ch<'0'||ch>'9') ch=getchar();
    while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
}
int T,n,m,k;
int a[maxn],pre[maxn],head[1005],f[maxn][maxn];
int main(){
    read(T);
    while(T--){
        read(n);read(m);read(k);
        memset(head,0,sizeof(head));
        for(int i=1;i<=n;++i){
            read(a[i]); pre[i]=head[a[i]]; head[a[i]]=i;
        }
        memset(head,0,sizeof(head));
        for(int i=n;i>=1;--i){
            head[a[i]]=i;
            for(int j=i;j<=n;++j){
                int k=head[a[j]],p=pre[j],w=(p<k&&k<=j)+(p<=k&&k<j);
                f[i][j]=(f[i][j-1]-f[k+1][p-1]+f[k+1][j-1]+w)%mo;
                if(f[i][j]<0) f[i][j]+=mo;
            }
        }
        for(int i=1;i<=m;++i){
            int x,y; read(x);read(y);
            printf("%d
",f[x][y]);
        }
    }
    return 0;
}
View Code
欢迎转载,转载请注明出处!
原文地址:https://www.cnblogs.com/huihao/p/7748364.html