给定序列A,求出A中本质不同的子序列(包含空的子序列)个数模109+7的结果.
一个序列B是A的子序列需要满足A删掉某些元素后能够得到B.
两个子序列中对应位置的数都相同我们就认为这两个子序列本质相同.
今晚卡题打崩了。
以后不能死啃一道题啊。
这场好题蛮多的,慢慢补。
I.序列本质
5
2 3 1 3 2
27
#include <bits/stdc++.h>
#define maxn 1000005
using namespace std;
typedef long long ll;
const ll mod = 1e9+7;
ll a[maxn];
ll f[maxn];
ll ans[maxn];
int last[maxn];
int main()
{
/*我们设f[i]为以a[i]结尾的,不同子序列数
*设 ans[i]为1-i的不同方法数
* 则有 f[i]=ans[i-1]+1
* ans[i]=ans[i-1]+f[i](如果f[i]没有出现过)
* ans[i]=ans[i-1]+f[i]-f[last[a[i]]]
*/
int n;
scanf("%d",&n);
ans[1]=1;
f[1]=1;
for(int i=1;i<=n;++i)
{
scanf("%lld",&a[i]);
}
last[a[1]]=1;
for(int i=2;i<=n;++i)
{
f[i]=(ans[i-1]+1)%mod;
if(last[a[i]]==0)
{
ans[i]=(ans[i-1]+f[i])%mod;
}
else
{
ans[i]=(ans[i-1]+f[i]-f[last[a[i]]]+mod)%mod;
}
last[a[i]]=i;
}
printf("%lld\n",(ans[n]+1));
return 0;
}
5
1 3
5 2
4 3
3 5
2
可以选择邀请学生2&3,或者是邀请学生3&5
对于前10%的数据,n<=15
对于前30%的数据,n<=2000
对于接下来30%的数据,n<=10^5,且有俩学生需要通过n-1条绯闻才能扯上关系。
对于前100%的数据,n<=10^5,1<=x,y<=n
#include <bits/stdc++.h>
#define maxn 100005
using namespace std;
struct Edge
{
int v,next;
};
pair<int,int> depth[maxn];
bool col[maxn];
struct Map
{
int head[maxn];
int fa[maxn];
Edge edge[maxn*2];
int cnt;
void init()
{
memset(head,-1, sizeof(head));
cnt=0;
}
void addedge(int u,int v)
{
edge[cnt].v=v;
edge[cnt].next=head[u];
head[u]=cnt++;
}
void bfs(int s)
{
bool vis[maxn]={0};
queue<int> que;
depth[1].first=0;
depth[1].second=1;
que.push(s);
vis[s]=true;
while(!que.empty())
{
int u=que.front();
que.pop();
for(int i=head[u];i!=-1;i=edge[i].next)
{
int v=edge[i].v;
if(!vis[v])
{
vis[v]=true;
fa[v]=u;
depth[v].first=depth[u].first+1;
depth[v].second=v;
que.push(v);
}
}
}
}
void color(int num)
{
col[num]=true;
for(int i=head[num];i!=-1;i=edge[i].next)
{
col[edge[i].v]=true;
}
}
}Mp;
bool cmp(pair<int,int> a,pair<int,int> b)
{
return a.first>b.first;
}
int main()
{
int n;
scanf("%d",&n);
Mp.init();
for(int i=1;i<=n-1;++i)
{
int u,v;
scanf("%d%d",&u,&v);
Mp.addedge(u,v);
Mp.addedge(v,u);
}
int ans=0;
Mp.bfs(1);
sort(depth+1,depth+1+n,cmp);
for(int i=1;i<=n;++i)
{
int v=depth[i].second;
int f=Mp.fa[v];
if(col[v]) continue;
++ans;
Mp.color(f);
}
printf("%d\n",ans);
return 0;
}
原文:https://www.cnblogs.com/zyf3855923/p/9938621.html