11.9训练记录
今晚卡题打崩了。
以后不能死啃一道题啊。
这场好题蛮多的,慢慢补。
I.序列本质
题目描述
给定序列A,求出A中本质不同的子序列(包含空的子序列)个数模109+7的结果.
一个序列B是A的子序列需要满足A删掉某些元素后能够得到B.
两个子序列中对应位置的数都相同我们就认为这两个子序列本质相同.
一个序列B是A的子序列需要满足A删掉某些元素后能够得到B.
两个子序列中对应位置的数都相同我们就认为这两个子序列本质相同.
输入
第一行包含一个整数N,代表序列的长度.接下来一行N个整数,第i个数代表Ai.
输出
输出一个整数代表答案。
样例输入
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; }
L: 开会
题目描述
开会,是对所有人时间的浪费,是对集体的谋杀。
山区学校的一些学生之间的关系似乎好得有点过头,以至于传出了一些(在风纪委员们看来)不好的绯闻。具体地,有n个学生,n-1条绯闻,每条绯闻的主角都是俩学生。记者们的恶趣味保证任意两个学生,可以通过若干条绯闻直接或间接地联系在一起。
于是学校打算邀请一些学生参加座谈会。
校长相信,假如邀请了某位学生x来开会,那么就能够震慑到x本人,以及和x在同一条绯闻里的学生们。
矿泉水是宝贵的,校长想知道最少需要请多少人来开会,才有可能震慑到所有同学。
山区学校的一些学生之间的关系似乎好得有点过头,以至于传出了一些(在风纪委员们看来)不好的绯闻。具体地,有n个学生,n-1条绯闻,每条绯闻的主角都是俩学生。记者们的恶趣味保证任意两个学生,可以通过若干条绯闻直接或间接地联系在一起。
于是学校打算邀请一些学生参加座谈会。
校长相信,假如邀请了某位学生x来开会,那么就能够震慑到x本人,以及和x在同一条绯闻里的学生们。
矿泉水是宝贵的,校长想知道最少需要请多少人来开会,才有可能震慑到所有同学。
输入
第一行是 n 表示学生数。
之后n-1行,每行俩整数x,y,表示学生x和y之间有绯闻。( x≠y,但不一定x<y )
之后n-1行,每行俩整数x,y,表示学生x和y之间有绯闻。( x≠y,但不一定x<y )
输出
一行,一个整数表示最少要邀请多少人。
样例输入
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; }