A:pig站在传送带上只能在传送带上移动的情况下判断是否能够到达m初始位置0
题解:用dp[i]表示pig能不能到达接着转移方程就是在传送在dp[i] = max(dp[i-1],dp[i])即可
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
using namespace std;
#define root 1,1,n
#define ls 2*rt
#define rs 2*rt+1
#define mid (L+R)/2
#define lson ls,L,mid
#define rson rs,mid+1,R
const int mx = 1e5+5;
int l[mx];
int r[mx];
int dp[mx];
int main(){
int n,m;
memset(dp,0,sizeof(dp));
scanf("%d%d",&n,&m);
for(int i = 1; i <= n; i++)
scanf("%d%d",&l[i],&r[i]);
dp[0] = 1;
for(int i = 1; i <= n; i++)
for(int j = l[i]+1; j <= r[i]; j++)
dp[j] = max(dp[j-1],dp[j]);
if(dp[m])
puts("YES");
else
puts("NO");
return 0;
}
B:让你涂一棵树的颜色,涂完改结点后其所有子树都会变成该颜色,要求你涂成特定的颜色需要涂多少步
题解:直接从上往下涂判断是否为想要的颜色即可
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
#include<vector>
using namespace std;
#define root 1,1,n
#define ls 2*rt
#define rs 2*rt+1
#define mid (L+R)/2
#define lson ls,L,mid
#define rson rs,mid+1,R
const int mx = 1e5+5;
vector<int>g[mx];
int col[mx];
int ans;
void dfs(int u,int fa,int s){
if(s!=col[u])
ans++;
for(auto v: g[u]){
if(v!=fa){
dfs(v,u,col[u]);
}
}
}
int main(){
int n,m;
int a;
ans = 0;
scanf("%d",&n);
for(int i = 2; i <= n; i++){
scanf("%d",&a);
g[a].push_back(i);
}
for(int i = 1; i <= n; i++)
scanf("%d",&col[i]);
dfs(1,0,0);
printf("%d\n",ans);
return 0;
}
C::给你一课树,深度0-n,深度为然后是0-n的树判断是否能构造出不同构的树
题解:如果有两个以上高度连续且个数都为2以上的话肯定能构造出不同构的树,接着让同一高度的结点一个指向开始结点一个指向末尾结点即可
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
#include<vector>
using namespace std;
#define root 1,1,n
#define ls 2*rt
#define rs 2*rt+1
#define mid (L+R)/2
#define lson ls,L,mid
#define rson rs,mid+1,R
const int mx = 1e5+5;
int a[mx];
int main(){
int n,m;
scanf("%d",&n);
int ok = 1;
int sum = 0;
for(int i = 0; i <= n; i++){
scanf("%d",&a[i]);
sum += a[i];
}
for(int i = 1; i <= n; i++)
if(a[i]>=2&&a[i-1]>=2)
ok = 0;
if(ok)
puts("perfect");
else{
puts("ambiguous");
int pre = 0;
int len = 1;
for(int i = 0; i <= n; i++){
for(int j = 1; j <= a[i]; j++){
printf("%d%c",pre,len==sum?'\n':' ');
len++;
}
pre = len-1;
}
pre = 0;
len = 1;
int s = 0;
for(int i = 0; i <= n; i++){
for(int j = 1; j <= a[i]; j++){
printf("%d%c",j%2==0?s:pre,len==sum?'\n':' ');
len++;
}
pre = len-1;
s = len-a[i];
}
}
return 0;
}
D:给你一个公式然后判断多项式到达B等于0需要多少步
题解:设p1 = 1, p2 = x
p(n) = x*p(n-1) + p(n-2)即可
因为限制了系数只能为-1,0,1所以我们求得时候取膜2即可
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
const int mx = 1e5+5;
int a[300],b[300],c[300];
int n;
void calc(){
int *x,*y,*z;
x = a;
y = b;
z = c;
for(int i = 1; i < n; i++){
memset(z,0,sizeof(c));
for(int j = 0; j <= i; j++){
z[j+1] = x[j];
}
for(int j = 0; j < i; j++){
z[j] = (z[j]+y[j])%2;
// printf("%d",y[j]);
}
swap(x,z);
swap(z,y);
}
printf("%d\n",n);
for(int i = 0; i <= n; i++)
printf("%d%c",x[i],i==n?'\n':' ');
n--;
printf("%d\n",n);
for(int i = 0; i <= n; i++)
printf("%d%c",y[i],i==n?'\n':' ');
}
int main(){
scanf("%d",&n);
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
memset(c,0,sizeof(c));
a[0] = 0;
a[1] = 1;
b[0] = 1;
calc();
return 0;
}
E:给你n个点的无向图,保证没有偶数点的环,有q个查询,每次给l,r问只保留l,r编号的点,问有多少对区间内的点构成二分图
题解:如果都没有环的情况是(n+1)*n/2那么考虑一下有环的化我如果是这个环内编号的最小的或者比他小的点那么我只能延伸到环的最大点-1接着当给你l,r的时候我只要找出最右边的那个有环的最小点加1即可,这样分成两部分就是sum[l]-sum[x]+(r-x+2)*(r-x+1)/2,这些我们可以预处理一下在r位置的最右边的环的点是哪一个,接着就是求环我们当碰到已经遍历过的点那么我们可以用一个栈存一下一直后退直到栈顶的元素是我们遍历到的点即可.最后我这个点可能不在环内用另外一个数字标记一下即可
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<stack>
#include<set>
using namespace std;
typedef long long int ll;
const int mx = 3e5+5;
stack<int>s;
int front[mx];
vector<int>g[mx];
int pre[mx];
int Max[mx],Min[mx];
ll sum[mx];
void dfs(int u,int fa){
pre[u] = 1;
s.push(u);
for(auto v: g[u]){
if(v!=fa){
if(pre[v]==0) dfs(v,u);
else if(pre[v]==1){
int x = u,y = u;
while(!s.empty()){
int z = s.top();
s.pop();
x = min(z,x);
y = max(z,y);
if(z==v) break;
}
Max[y] = x;
Min[x] = y;
}
}
}
if(!s.empty()&&s.top()==u) s.pop();
pre[u] = 2;
}
int main(){
int n,m,q;
scanf("%d%d",&n,&m);
for(int i = 1; i <= m; i++){
int u,v;
scanf("%d%d",&u,&v);
g[u].push_back(v);
g[v].push_back(u);
}
for(int i = 0; i <= n+1; i++)
Max[i] = 0,Min[i] = n+1;
for(int i = 1; i <= n; i++)
if(!pre[i])
dfs(i,i);
int x,y;
for(int i = n; i >= 1; i--){
Min[i] = min(Min[i+1],Min[i]);
sum[i] = sum[i+1] + Min[i]-i;
}
for(int i = 1; i <= n; i++){
Max[i] = max(Max[i-1],Max[i]);
cout<<Max[i]<<endl;
}
scanf("%d",&q);
while(q--){
int l,r;
scanf("%d%d",&l,&r);
x = max(l,Max[r]+1);
//cout<<x<<endl;
ll ans = sum[l]-sum[x];
//cout<<ans<<endl;
ans += 1ll*(r-x+2)*(r-x+1)/2;
printf("%I64d\n",ans);
}
return 0;
}
给你