ZSJZ训练 2020.06.06【NOIP提高组】模拟 反思&题解

今天100分,第8,日常只做对一道签到题,呜呜呜……

T1:【USACO 2017 December Silver】The Bovine Shuffle

Description

Convinced that happy cows generate more milk, Farmer John has installed a giant disco ball in his barn and plans to teach his cows to dance! Looking up popular cow dances, Farmer John decides to teach his cows the “Bovine Shuffle”. The Bovine Shuffle consists of his N cows (1≤N≤100,000) lining up in a row in some order, then performing successive “shuffles”, each of which potentially re-orders the cows. To make it easier for his cows to locate themselves, Farmer John marks the locations for his line of cows with positions 1…N, so the first cow in the lineup will be in position 1, the next in position 2, and so on, up to position N.

A shuffle is described with N numbers, a1…aN, where a cow in position i moves to position ai during the shuffle (and so, each ai is in the range 1…N). Every cow moves to its new location during the shuffle. Unfortunately, all the ai’s are not necessarily distinct, so multiple cows might try to move to the same position during a shuffle, after which they will move together for all remaining shuffles.

Farmer John notices that some positions in his lineup contain cows in them no matter how many shuffles take place. Please help him count the number of such positions.
FJ 坚信快乐的牛可以产出更多的牛奶,因此 FJ 在牛棚里安装了一个巨大的迪斯科球并且打算让奶牛们学会跳舞。
FJ在许多出名的奶牛舞中选择了一种叫做 Bovine Shuffle 的舞蹈。这种舞蹈由 FJ 的 N 头奶牛组成。N头奶牛以一种顺序排成一行,接着表演数次 shuffle。每次的 shuffle 会将奶牛重新排列。FJ 为了让奶牛们更加快乐,让奶牛们更容易找到重新排列后的位置,他标记了 N 头奶牛的位置。在最开始,所有奶牛排成一排,第一头奶牛会在位置 1 上,第二只在 2上,以此类推。
我们用 N 个正整数 a1,a2,…,an来描述每次的 shuffle。ai说明了在位置 i上的奶牛在经过这回合的 shuffle 之后,会跑到位置 ai上。令 FJ 倍感非洲的是,即使 i与j不同,ai也可能会等于 aj!所以可能在一次 shuffle 后,有多头奶牛会跑到同一位置上,在这之后这群奶牛也会一同行动。
作为一名资深的养牛大户&坑牛专家的 FJ 猛然发现,无论经过多少次的 shuffle,一直都有 k个位置上有奶牛。FJ现在要你在 1秒内帮他得出 kk 的值,否则就赏你 10^18 mod10 大板!

Input

he first line of input contains N, the number of cows. The next line contains the N integers a1…aN.
第一行包含一个整数,N
第二行包含 NN个整数,描述题目中的a 1 ​ ,a 2 ​ …a n ​

Output

Please output the number of positions that will always contain cows, no matter how many shuffles take place.
一个整数,代表k

Sample Input

4
3 2 1 3

Sample Output

3

反思&题解

考试&正解思路: 双向模拟搞一搞,轻松过(还可以用判环的方法,本蒟蒻只会打水法)
反思: 签到题,水,秒切

CODE

#include
using namespace std;
int n,b1[100005],b2[100005],a[100005],ans;
int main()
{
	freopen("shuffle.in","r",stdin);
	freopen("shuffle.out","w",stdout);
    scanf("%d",&n);
    int i;
    for (i=1;i<=n;i++)
    {
    	scanf("%d",&a[i]);
		b1[i]=1;
		b2[i]=1;
	}
	int j;
    for (i=1;i<=1000;i++)
    {
        for (j=1;j<=n;j++)
			b2[a[j]]+=b1[j];
        memset(b1,0,sizeof(b1));
        for (j=1;j<=n;j++)
			b1[a[j]]+=b2[j];
        memset(b2,0,sizeof(b2));
    }
    for (i=1;i<=n;i++)
    {
    	if (b1[i]) ans++;
	}
	printf("%d\n",ans);
    return 0;
} 

T2:【USACO 2017 December Silver】Milk Measurement

Description

Each of Farmer John’s cows initially produces G gallons of milk per day (1≤G≤109). Since the milk output of a cow is known to potentially change over time, Farmer John decides to take periodic measurements of milk output and write these down in a log book. Entries in his log look like this:
35 1234 -2
14 2345 +3
The first entry indicates that on day 35, cow #1234’s milk output was 2 gallons lower than it was when last measured. The next entry indicates that on day 14, cow #2345’s milk output increased by 3 gallons from when it was last measured. Farmer John has only enough time to make at most one measurement on any given day. Unfortunately, he is a bit disorganized, and doesn’t necessarily write down his measurements in chronological order.

To keep his cows motivated, Farmer John proudly displays on the wall of his barn the picture of whichever cow currently has the highest milk output (if several cows tie for the highest milk output, he displays all of their pictures). Please determine the number of days on which Farmer John would have needed to change this display.

Note that Farmer John has a very large herd of cows, so although some of them are noted in his log book as changing their milk production, there are always plenty of other cows around whose milk output level remains at G gallons.
最初,农夫约翰的每头奶牛每天生产G加仑的牛奶(1≤G≤10^9)。由于随着时间的推移,奶牛的产奶量可能会发生变化,农夫约翰决定定期对奶牛的产奶量进行测量,并将其记录在日志中。
他的日志中的记录如下:
35 1234 -2
14 2345 +3
第一个条目表明:在第35天,1234号奶牛的产奶量比上次测量时降低了2加仑。
第二个条目表明:在第14天,2345号奶牛的产奶量比上次测量时增加了3加仑。
农夫约翰只有在任何一天内做最多一次测量的时间(即每天最多做一次测量,但可能不做)。不幸的是,约翰有点杂乱无章,他不一定按照时间顺序记下测量结果。为了保持奶牛的产奶动力,农夫约翰自豪地在谷仓的墙上展示了目前产奶量最高的奶牛的照片(如果有若干头奶牛的产奶量最高,他就会展示所有的图片)。

请求出约翰需要调整所展示的照片的次数。

请注意,农夫约翰有一大群奶牛。所以尽管日志中记录了一些奶牛改变了产奶量,但仍然还有很多奶牛的产奶量保持在G加仑。

Input

The first line of input contains the number of measurements N that Farmer John makes (1≤N≤100,000), followed by G. Each of the next N lines contains one measurement, in the format above, specifying a day (an integer in the range 1…10^6), the integer ID of a cow (in the range 1…10^9), and the change in her milk output since it was last measured (a nonzero integer). Each cow’s milk output will always be in the range 0…10^9.
第一行是两个整数N和G,分别表示测量的次数和初始产奶量。
接下来N行,每行为一次测量。每行三个数:分别表示日期一(在整数1…106范围内),奶牛的编号(在整数1…109范围内),该奶牛的产奶量变化值(一个非负数)。无论如何,每头奶牛的产奶量永远保证在0…10^9范围内。

Output

Please output the number of days on which Farmer John needs to adjust his motivational display.
请输出约翰总共调整所展示的照片的次数。

Sample Input

4 10
7 3 +3
4 2 -1
9 3 -1
1 1 +2

Sample Output

3

反思&题解

正解思路: 模拟,分情况判断处理就行了(还可以用线段树、平衡树,本蒟蒻照常打水法)
反思: 考试时的思维要发散一点,不能局限与一点

CODE

#include
using namespace std;
map<int,int>h;
struct arr
{
	int day,w,ch;	
}a[100005];
bool cmp(arr l,arr r)
{
	return l.day<r.day;
}
int n,g,tot,ans,sum,sum2,first,second,b[100005];
int read()
{
	int x,f;
	char ch;
	x=0;
	f=1;
	ch=getchar();
	while (ch<'0' || ch>'9')
	{
		if (ch=='-') f=-1;
		ch=getchar();	
	}
	while (ch>='0' && ch<='9')
	{
		x=x*10+ch-'0';
		ch=getchar();
	}
	return x*f;
}//以为过不了,就打了个快读
void cz()
{
	int i;
	sum2=-0x3f3f3f3f;
	second=0;
	for (i=1;i<=tot;i++)
	{
		if (b[i]!=sum && b[i]>sum2)
		{
			sum2=b[i];
			second=1;
		}
		else if (b[i]==sum2) second++;
	}
}
int main()
{
	freopen("measurement.in","r",stdin);
	freopen("measurement.out","w",stdout);
	n=read();
	g=read();
	int i;
	for (i=1;i<=n;i++)
	{
		a[i].day=read();
		a[i].w=read();
		a[i].ch=read();
	}
	sort(a+1,a+1+n,cmp);
	tot=1;
	for (i=1;i<=n;i++)
	{
		if (!h[a[i].w])
		{
			tot++;
			h[a[i].w]=tot;
		}
		if (b[h[a[i].w]]==sum)
		{
			b[h[a[i].w]]+=a[i].ch;
			if (a[i].ch>0)
			{
				if (first!=1)
				{
					sum2=sum;
					second=first-1;
					sum=b[h[a[i].w]];
					first=1;
					ans++;
				}
				else sum=b[h[a[i].w]];
			}
			else
			{
				if (first!=1)
				{
					first--;
					ans++;
					if (b[h[a[i].w]]>sum2)
					{
						sum2=b[h[a[i].w]];
						second=1;
					}
					if (b[h[a[i].w]]==sum2) second++;
				}
				else
				{
					if (b[h[a[i].w]]>sum2) sum=b[h[a[i].w]];
					if (b[h[a[i].w]]==sum2)
					{
						sum=sum2;
						first=second+1;
						ans++;
						cz();
					}
					if (b[h[a[i].w]]<sum2)
					{
						sum=sum2;
						first=second;
						ans++;
						cz();
					}
				}
			}
		}
		else if (b[h[a[i].w]]==sum2)
		{
			b[h[a[i].w]]+=a[i].ch;
			if (a[i].ch<0)
			{
				second--;
				if (!second) cz();
			}
			else
			{
				if (b[h[a[i].w]]==sum)
				{
					second--;
					first++;
					ans++;
					if (!second) cz();
				}
				else
				{
					sum2=b[h[a[i].w]];
					second=1;
					if (sum2>sum)
					{
						swap(sum2,sum);
						swap(second,first);
						ans++;
					}
				}
			}
		}
		else
		{
			b[h[a[i].w]]+=a[i].ch;
			if (b[h[a[i].w]]==sum2) second++;
			if (b[h[a[i].w]]==sum)
			{
				first++;
				ans++;
			}
			else if (b[h[a[i].w]]>sum2)
			{
				sum2=b[h[a[i].w]];
				second=1;
				if (sum2>sum)
				{
					swap(sum2,sum);
					swap(second,first);
					ans++;
				}
			}
		}
	}
	
	printf("%d\n",ans);
	return 0; 
}

T3:【USACO 2017 December Gold】Barn Painting

Description

Farmer John has a large farm with N barns (1≤N≤10^5), some of which are already painted and some not yet painted. Farmer John wants to paint these remaining barns so that all the barns are painted, but he only has three paint colors available. Moreover, his prize cow Bessie becomes confused if two barns that are directly reachable from one another are the same color, so he wants to make sure this situation does not happen. It is guaranteed that the connections between the N barns do not form any ‘cycles’. That is, between any two barns, there is at most one sequence of connections that will lead from one to the other.

How many ways can Farmer John paint the remaining yet-uncolored barns?
给定一颗N个节点组成的树,3种颜色,其中K个节点已染色,要求任意两相邻节点颜色不同,求合法染色方案数。

Input

The first line contains two integers N and K (0≤K≤N), respectively the number of barns on the farm and the number of barns that have already been painted.

The next N−1 lines each contain two integers x and y (1≤x,y≤N,x≠y) describing a path directly connecting barns x and y.

The next K lines each contain two integers b and c (1≤b≤N, 1≤c≤3) indicating that barn b is painted with color c.

Output

Compute the number of valid ways to paint the remaining barns, modulo 10^9+7, such that no two barns which are directly connected are the same color.

Sample Input

4 1
1 2
1 3
1 4
4 3

Sample Output

8

反思&题解

正解思路: 树形DP,f[i][j]表示i点涂第j种颜色的方案数,方程:
f [ k ] [ 1 ] = f [ k ] [ 1 ] ∗ ( ( f [ v ] [ 2 ] + f [ v ] [ 3 ] ) ) f[k][1]=f[k][1]*((f[v][2]+f[v][3])) f[k][1]=f[k][1]((f[v][2]+f[v][3]))
f [ k ] [ 2 ] = f [ k ] [ 2 ] ∗ ( ( f [ v ] [ 1 ] + f [ v ] [ 3 ] ) ) f[k][2]=f[k][2]*((f[v][1]+f[v][3])) f[k][2]=f[k][2]((f[v][1]+f[v][3]))
f [ k ] [ 3 ] = f [ k ] [ 3 ] ∗ ( ( f [ v ] [ 2 ] + f [ v ] [ 1 ] ) ) f[k][3]=f[k][3]*((f[v][2]+f[v][1])) f[k][3]=f[k][3]((f[v][2]+f[v][1]))
还有几个小细节,还有不要忘记mod
反思: 考试的时候我也是这个思路,可惜预处理的地方打错了,导致调不出来,树形DP要多练

CODE

#include
using namespace std;
const long long mo=1000000007;
int n,k,head[100005],c[100005],cnt;
long long f[100005][4];
bool bz[100005];
struct arr
{
	int next,to;
}edge[200005];
void add(int u,int v)
{
	edge[++cnt].next=head[u];
	edge[cnt].to=v;
	head[u]=cnt;
}
void dg(int k)
{
	bz[k]=true;
	if (c[k]) f[k][c[k]]=1;
	else
	{
		f[k][1]=1;
		f[k][2]=1;
		f[k][3]=1;
	}
	int i;
	for (i=head[k];i;i=edge[i].next)
	{
		int v=edge[i].to;
		if (!bz[v])
		{
			dg(v);
			f[k][1]=f[k][1]*((f[v][2]+f[v][3])%mo)%mo;
			f[k][2]=f[k][2]*((f[v][1]+f[v][3])%mo)%mo;
			f[k][3]=f[k][3]*((f[v][2]+f[v][1])%mo)%mo;
		}
	}
}
int main()
{
	freopen("barnpainting.in","r",stdin);
	freopen("barnpainting.out","w",stdout);
	scanf("%d%d",&n,&k);
	int i;
	for (i=1;i<n;i++)
	{
		int u,v;
		scanf("%d%d",&u,&v);
		add(u,v);
		add(v,u);
	}
	for (i=1;i<=k;i++)
	{
		int x,color;
		scanf("%d%d",&x,&color);
		c[x]=color;
	}
	dg(1);
	printf("%lld\n",(f[1][1]+f[1][2]+f[1][3])%mo);
}

你可能感兴趣的:(反思,题解)